Skip to content

Latest commit

 

History

History
57 lines (42 loc) · 1.34 KB

File metadata and controls

57 lines (42 loc) · 1.34 KB

条款36:绝不重新定义继承而来的non-virtual函数

考虑如下代码:

class B {
public:
  void mf();
  ...
};
class D : public B {...};

面对一个类型为D的对象:

D x;

如果有以下行为:

B* pb = &x;
pb->mf();

异于以下行为:

D* pd = &x;
pD->mf();

如果mf是个non-virtual函数而D定义有自己的mf版本,那就会发生上述情况:

class D : public B {
public:
  void md();
  ...
};
pb->mf(); // B::mf
pd->mf(); // D::mf

造成此行为的原因是,non-virtual函数都是静态绑定。由于pb被声明为B指针,通过pb调用的non-virtual函数永远是B的版本。

条款32说过,public继承意味着is-a的关系。条款34描述为什么在class内声明一个non-virtual函数会为该class建立一个不变性,凌驾其特异性。将这两个观点施行于两个class B和D和non-virtual成员函数mf上,那么:

  • 适用于B对象的每一件事,也适用于D对象,因为每个D对象都是一个B对象。
  • B的派生类一定会继承mf的接口和实现,因为mf是B的non-virtual函数。

现在,如果D重新定义mf,你的设计便会出现矛盾。任何情况下都不该重新定义一个继承而来的non-virtual函数。

请记住

  • 绝对不要重新定义继承而来的non-virtual函数。