zoukankan      html  css  js  c++  java
  • 子类构造函数中调用虚函数问题验证

     一、问题探讨

      大家是否有在子类或基类构造函数中调用虚函数的情况呢?语法是否支持?执行情况如何呢?为什么呢?

    二、问题验证

      这个问题的最好答案是亲自写个demo调试下看看结果如何,下面是demo代码(vs2019):

     1 class Base {
     2 public:
     3     Base() {
     4         cout << "Base::ctor
    ";
     5         Func();
     6     }
     7     virtual void Func() {
     8         cout << "Base::Func
    ";
     9     }
    10 };
    11 
    12 class D : public Base {
    13 public:
    14     D() {
    15         cout << "D::ctor
    ";
    16         Func();
    17     }
    18 
    19     void Func() override {
    20         cout << "D::Func
    ";
    21     }
    22 };

      客户端调用代码

    1 int main()
    2 {
    3     auto d = std::make_shared<D>();
    4 
    5     return 0;
    6 }

      输出结构如下:

          

       子类构造函数调用虚函数调用的是子类重写的,基类构造函数调用的是基类的虚函数。可以回答问题中的前两个疑问,语法支持,执行情况如上;但是并没有调用子类重新的虚函数呢?继续分析。

    三、原因分析

      回答这个问题,我们可以直接使用VS2019的调试器即可。我们需要在基类和子类的构造函数中分别打上断点,如下:

        

       我们知道构造子类前需要先构造基类,在进入基类构造函数实现体前,虚函数表是空的:

       

      进入构造体后,虚表指向基类的虚函数地址:

       

       进入子类构造体前,虚表还是基类的虚函数地址:

       

       进入子类构造体后,虚表地址替换为子类的:

       

      通过上面详细的调试步骤和对象内存虚表信息即可知道为什么了吧!

  • 相关阅读:
    行列式学习笔记
    二项式反演学习笔记
    【AtCoder】ARC096(C
    【LOJ】#2127. 「HAOI2015」按位或
    [ACM] POJ 1218 THE DRUNK JAILER (关灯问题)
    lua的弱弱引用表
    西班牙式软件团队
    【DRP】採用dom4j完毕XML文件导入数据库
    基于Linux平台病毒Wirenet.c解析
    【剑指offer】异或去重
  • 原文地址:https://www.cnblogs.com/smartNeo/p/14584428.html
Copyright © 2011-2022 走看看