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的调试器即可。我们需要在基类和子类的构造函数中分别打上断点,如下:

        

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

       

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

       

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

       

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

       

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

  • 相关阅读:
    POJ 2892 Tunnel Warfare(树状数组+二分)
    POJ 2886 Who Gets the Most Candies?(树状数组+二分)
    POJ 2492 A Bug's Life(并查集)
    POJ 1182 食物链(并查集)
    POJ 1703 Find them, Catch them(种类并查集)
    TC SRM 582 DIV 2
    函数
    shell进阶--流程
    计划任务 at,cron
    kill命令
  • 原文地址:https://www.cnblogs.com/smartNeo/p/14584428.html
Copyright © 2011-2022 走看看