C++中不应该为从基类继承的non-virtual函数重新定义

在C++中,派生类不应该对从基类继承的non-virtual函数重新定义,首先看下面一段代码:

 1 class B
 2 {
 3 public:
 4 void mf();
 5 ...
 6 };
 7 
 8 class D:public B
 9 {
10 ...
11 };
12 
13 D x;
14 B* pb = &x;
15 pb->mf();
16 
17 D* pd = &x;
18 pd->mf();

上面的代码中第15行和第18行调用的函数都是mf,且pb和pd都是指向对象D的,那么这两次调用是否是同一个函数呢?答案是不一定,因为如果D中重新定义了mf函数,那么15行调用的是B::mf(),而第18行则调用的是D::mf(),因为不同于virtual的动态绑定(导致的结果是调用的函数是指针指向的对象的函数,即两次都是调用D的mf函数),这里的non-virtual是静态绑定的,B和D中都有各自的mf版本,调用不决定于指针所指的对象,而是指针的类型。这便造成了D即派生类对象调用同一函数的行为不一致性,因为具体的行为不取决于D对象,而取决于指向D对象的指针类型。

此外,基于public继承是"is a"的关系,也不应该在派生类中重新定义non-virtual函数,这是因为对于non-virtual函数,派生类继承了接口和实现,因而如果重新定义实现,B就不是一个D了,违背了public继承的实质。

 

以上整理自Effective C++中文版第三版case 36.

posted on 2013-06-04 22:05  Sophia-呵呵小猪  阅读(167)  评论(0编辑  收藏  举报