C++ 不要重新定义继承的非虚函数
不要重新定义继承的非虚函数
如果基类和派生类有相同的非虚函数,会有什么情况发生?
看下面的例子:
class B {public: void mf();};void B::mf(){cout << "Call B::mf() Function !" << endl;}class D: public B { ... };int main(){D x; // x是类型D的一个对象B *pB = &x; // 得到x的指针pB->mf(); // 通过指针调用mfD *pD = &x; // 得到x的指针pD->mf(); return 0;}输出结果:
Call B::mf() Function !
Call B::mf() Function !
这两种情况调用的mf()都是B.mf(),因为类D并没有重新定义自己的mf()函数,而是继承的B的函数。
但是若D这样定义:
class D: public B {public: void mf(); // 隐藏了B::mf; 参见条款50};输出结果:
Call B::mf() Function !
Call D::mf() Function !
那么pB->mf(); 调用的是B::mf(),而pD->mf();调用的则是D::mf()。
行为的两面性产生的原因在于,B::mf和D::mf非虚函数是静态绑定,因为pB被声明为指向B的指针类型,通过pB调用非虚函数时将总是调用那些定义在类B中的函数 ---- 即使pB指向的是从B派生的类的对象,如上例所示。
相反,虚函数是动态绑定的,因而不会产生这类问题。如果mf是虚函数,通过pB或pD调用mf时都将导致调用D::mf,因为pB和pD实际上指向的都是类型D的对象。
mf()是虚函数的情况:
#include <iostream>using namespace std;class B {public:virtual void mf();};void B::mf(){cout << "Call B::mf() Function !" << endl;}class D: public B {public : void mf();};void D::mf(){cout << "Call D::mf() Function!"<< endl;}int main(){D x; // x是类型D的一个对象B *pB = &x; // 得到x的指针pB->mf(); // 通过指针调用mfD *pD = &x; // 得到x的指针pD->mf(); return 0;}输出:
Call D::mf() Function!
Call D::mf() Function!