1.虚函数中的默认值
根据输出结果,可以看到最终调用的是子类的fun()函数,并且使用了基类函数fun()中的默认值。
默认参数是不会做为判断函数是否相同的因素的。所以子类与基类中的fun()函数被认为是相同的,这样基类的fun()函数被隐藏了。另外,默认值是在编译期间使用的。当编译器看到一个函数调用中的某个参数缺失了,它就会用默认提供的值来替换。因此,上面程序中,x的值在编译期间被替换了,在运行时期间调用的是子类的fun()函数。
2.基类默认值覆盖子类默认值
参考下面程序的结果:
#include <iostream> using namespace std; class Base { public: virtual void fun ( int x =100) //如果此处基类没有默认值,而子类去写了默认值直接编译报错。 { cout << "Base::fun(), x = " << x << endl; } }; class Derived : public Base { public: virtual void fun ( int x=999 )//编译期间就会被替换成基类的默认参数100 //子类写与不写默认值都可以,都是使用基类的默认值 { cout << "Derived::fun(), x = " << x << endl; } };
int main()
{
Derived d1;
Base *bp = &d1;
bp->fun();
return 0;
}
输出:
-
#include <iostream>
-
using namespace std;
-
class Base
-
{
-
public:
-
virtual void fun ( int x = 0)
-
{
-
cout << "Base::fun(), x = " << x << endl;
-
}
-
};
-
class Derived : public Base
-
{
-
public:
-
virtual void fun ( int x = 10 ) // 注意这里的变化
-
{
-
cout << "Derived::fun(), x = " << x << endl;
-
}
-
};
-
int main()
-
{
-
Derived d1;
-
Base *bp = &d1;
-
bp->fun();
-
return 0;
-
}
输出:
Derived::fun(), x = 0
这个程序的结果与前面的程序是一样的。原因也是一样的,默认值在编译期间被替换了。bp是基类类型的指针,调用fun函数时,编译器用0替换掉了10.
总的来说,应该尽量避免在虚函数中使用默认值,这样可以避免遇到一些意想不到的结果。