zoukankan      html  css  js  c++  java
  • 读书笔记_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 }

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

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

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

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

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

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

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

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

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

  • 相关阅读:
    一、ThinkPHP的介绍
    一、ThinkPHP的介绍
    perl 爬虫两个技巧
    perl 爬虫两个技巧
    perl 爬取上市公司业绩预告
    perl lwp get uft-8和gbk
    perl lwp get uft-8和gbk
    perl 爬取同花顺数据
    perl 爬取同花顺数据
    php 接口示例
  • 原文地址:https://www.cnblogs.com/jerry19880126/p/3597626.html
Copyright © 2011-2022 走看看