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.
总的来说,应该尽量避免在虚函数中使用默认值,这样可以避免遇到一些意想不到的结果。