读书笔记_Effective_C++_条款三十六:决不重新定义继承而来的non-virtual函数

这个条款的内容很简单,见下面的示例:

读书笔记_Effective_C++_条款三十六:决不重新定义继承而来的non-virtual函数
 1 class BaseClass
 2 {
 3 public:
 4     void NonVirtualFunction()
 5     {
 6         cout << "BaseClass::NonVirtualFunction" << endl;
 7     }
 8 };
 9 
10 class DerivedClass: public BaseClass
11 {
12 public:
13     void NonVirtualFunction()
14     {
15         cout << "DerivedClass::NonVirtualFunction" << endl;
16     }
17 };
18 
19 int main()
20 {
21     DerivedClass d;
22     BaseClass* bp = &d;
23     DerivedClass* dp = &d;
24     bp->NonVirtualFunction(); // 输出BaseClass::NonVirtualFunction
25     dp->NonVirtualFunction(); // 输出DerivedClass::NonVirtualFunction
26 }
读书笔记_Effective_C++_条款三十六:决不重新定义继承而来的non-virtual函数

从输出结果可以看到一个有趣的现象,那就是两者都是通过相同的对象d调用成员函数NonVirutalFunction,但显示结果却不相同,这会给读者带来困惑。

现在这个现象的原因是在于BaseClass:NonVirutalFunction与DerivedClass:NonVirtualFunction都是静态绑定,所以调用的non-virtual函数都是各自定义的版本。

 

回顾下之前的条款,如果是public继承的话,那么:

1) 适用于BaseClass的行为一定适用于DerivedClass,因为每一个DerivedClass对象都是一个BaseClass对象;

2) 如果BaseClass里面有非虚函数,那么DerivedClass一定是既继承了接口,也继承了实现;

3) 子类里面的同名函数会掩盖父类的同名函数,这是由于搜索法则导致的。

 

如果DerivedClass重定义一个non-virtual函数,那么会违反上面列出的法则。以第一条为例,如果子类真的要重定义这个函数,那么说明父类的这个函数不能满足子类的要求,这就与每一个子类都是父类的原则矛盾了。

 

可以总结一下了,无论哪一个观点,结论都相同:

任何情况下都不该重新定义一个继承而来的non-virtual函数。

读书笔记_Effective_C++_条款三十六:决不重新定义继承而来的non-virtual函数,布布扣,bubuko.com

读书笔记_Effective_C++_条款三十六:决不重新定义继承而来的non-virtual函数

上一篇:Java函数式编程(二)


下一篇:Spring-Context之三:使用XML和Groovy DSL配置Bean