本文作者:islwj
本文出处:http://blog.csdn.net/islwj
声明: 本文可以不经作者同意, 任意复制, 转载, 但任何对本文的引用都请保留文章开始前三行的作者, 出处以及声明信息. 谢谢

  林锐博士对覆盖规则的定义如下:

  (1)不同的范围(分别位于派生类与基类);
  (2)函数名字相同;
  (3)参数相同;
  (4)基类函数必须有virtual 关键字.

  这样来理解重载、隐藏、覆盖确实是有点令人困惑.其实这个(覆盖)定义就是类的虚函数的定义.即,基类中,必须有virtual关键字,派生类函数的原型必须相同.
  所谓的覆盖规则造成的调用现象,其实就是类的虚函数实现原理生成的.为了达到动态绑定(后期绑定)的目的,C++编译器通过某个表格(一般称为vtable),在执行期"间接"调用实际上欲绑定的函数.每一个内含虚函数的类,C++编译器都会为它做出一个虚函数表,表中的每一个元素都指向一个虚函数的地址.

举个例子:
    class base{
    public:
        func();
        virtual vfunc1();
        virtual vfunc2();
        virtual vfunc3();
    private:
        int _data1;
        int _data2;
    };
    base对象实例在内存中占据的空间是这样的:
     base对象实例          vtable
--------------------------------------------------------------------------
         vptr ---------> (*vfunc1)() -----------> base::vfunc1();
        _data1           (*vfunc2)() -----------> base::vfunc2();
        _data2           (*vfunc3)() -----------> base::vfunc3();
--------------------------------------------------------------------------

当派生类改写了虚函数时,虚函数表相应的被修改了:
    class derived: public base{
    public:
        vfunc2();
    };
    derived对象实例              vtable
--------------------------------------------------------------------------
         vptr  ---------> (*vfunc1)() -----------> base::vfunc1()      
        _data1;           (*vfunc2)() -----------> derived::vfunc2()     ****注意,这里变了!!!***
        _data2;           (*vfunc3)() -----------> base::vfunc3()
--------------------------------------------------------------------------

所以当你写下如下程序的时候:
    void main(void)
    {
        Derived d;
        Base *pb = &d;
        pb->vfunc2(); // Derived::vfunc2(void)
    }

就不难理解为何pb->vfunc2()调用的是derived::vfunc2()了,因为pb实际上指向派生类derived的实例,而派生类中的虚函数表已经被修改了.

简单来说,隐藏规则就是C++的名字解析过程,自里向外解析,这个好理解;而覆盖规则其实就是C++虚函数表的实现原理.这样就可以比较容易的区分这两个知识点,而不用老是背隐藏规则跟覆盖规则的细微区别.
    而重载规则的,简单来说就是我在 深入理解成员函数的重载、隐藏、覆盖规则(一) 中所列的特征.而具体呢,重载实在太多东西写了,涉及到模板、命名空间等,有空再写:)

(完--不是结局的结局.)

参考书籍:
    <The C++ Primer>      Stanley B Lippman、J o s é e L a j o i e
    <高质量C++编程>       林锐
    <深入浅出MFC第二版>   侯捷

注:以上例子主要来自<高质量C++编程>、<深入浅出MFC第二版>.

深入理解成员函数的重载、隐藏、覆盖规则(二)相关推荐

  1. 成员函数的重载、覆盖与隐藏(详细)【转】

    (转自:https://blog.csdn.net/weixin_42205987/article/details/81569744) 成员函数的重载.覆盖与隐藏 成员函数的重载(overload). ...

  2. c++成员函数的重载、覆盖、隐藏区别

    c++成员函数的重载.覆盖.隐藏区别 成员函数的重载.覆盖(override)与隐藏很容易混淆,C++程序员必须要搞清楚概念,否则错误将防不胜防. 重载与覆盖 成员函数被重载的特征: (1)相同的范围 ...

  3. C++成员函数的重载、覆盖与隐藏

    C++成员函数的重载.覆盖与隐藏 成员函数的重载.覆盖(override)与隐藏很容易混淆,C++程序员必须要搞清楚概念,否则错误将防不胜防. 重载与覆盖 成员函数被重载的特征: (1)相同的范围(在 ...

  4. C++中类成员函数的重载、覆盖和隐藏的区别,超清楚!

    转载:https://www.cnblogs.com/liubo1/p/5925746.html 1.成员函数被重载的特征: (1)相同的范围(在同一个类中): (2)函数名字相同: (3)参数不同: ...

  5. 成员函数的重载,覆盖与隐藏

    重载 具有相同的作用域(即同一个类定义中) 函数名字相同 参数类型.顺序或数目不同(包括const参数和非const参数) virtual关键字可有可无 覆盖 是指派生类重新实现(或改写)了基类的成员 ...

  6. 函数的重载、覆盖和隐藏

    从下面的这个例子中可以看到函数的重载.覆盖和隐藏的具体意思,以及它们之间的区别: #include<iostream> using namespace std; class CParent ...

  7. C++中的虚继承 重载隐藏覆盖的讨论

    虚继承这个东西用的真不多.估计也就是面试的时候会用到吧.. 可以看这篇文章:<关于C++中的虚拟继承的一些总结> 虚拟基类是为解决多重继承而出现的. 如:类D继承自类B1.B2,而类B1. ...

  8. c++ public 函数名相同_C++虚函数、重载、覆盖

    C++基础(五)虚函数.重载.覆盖.隐藏 虚函数总是跟多态联系在一起,引入虚函数可以使用基类指针对继承类对象进行操作!虚函数:继承接口(函数名,参数,返回值),但是实现不继承(函数体) 非虚函数:继承 ...

  9. C++学习笔记-----继承体系中函数的重载,覆盖和隐藏的区别

    1.重载,在同一个作用域中定义的同名不同参的一些函数为重载. 2.隐藏,若在基类中定义了某一non_virtual函数,在派生类重存在同名函数(不需要参数列表相同),基类的该函数在派生类中是不可见的, ...

最新文章

  1. 无线网络未来十年十大产业趋势
  2. opencv图像遍历方法速度对比
  3. stm32 外部中断学习
  4. .net中前台javascript与后台c#函数相互调用
  5. Qt文档阅读笔记-QHeaderView::sectionResized官方解析与实例
  6. 读书笔记—《发现你的行为模式(钻石版)》-DiSC测试
  7. Java教程:使用记事本编写运行Java程序
  8. JSP中Session的使用
  9. 温习ASP调用C#的DLL并实现用户名密码进行域验证反馈结果
  10. Android Studio实现前后台分离的选课系统
  11. 网站安全webshell扫描
  12. 【转载】C#, VB.NET如何将Excel转换为PDF
  13. C#与SQL实现医院信息管理系统
  14. 不想被淘汰,大咖有话说——程序猿一定要学大数据?
  15. PVID和VID详解
  16. java.util.MissingResourceException: Can‘t find resource for bundle java.util.PropertyResourceBundle
  17. KETTLE:通过代码运行本地ktr文件
  18. Delphi中BeginUpdate和EndUpdate作用
  19. FPS游戏UE4逆向视频教程
  20. 百度地图-初步的地图创建和标识

热门文章

  1. 第4章 简单的C程序设计——选择结构程序设计
  2. 很认真的聊一聊一个程序员的自我修养
  3. Structured Streaming中StructType与StructField的嵌套使用
  4. 微信小程序例子——鼠标拖动效果
  5. Win10 任务栏卡死,点击没反应,但是桌面依然可以正常使用,怎么办?
  6. Keras Recurrent Layers 解析
  7. Recurrent Neural Networks 简述
  8. CEGUI、DirectX和OIS结合
  9. Google Colab 使用
  10. Eclipse中手动安装PyDev