• C++ 学习基础十八——在构造(析构)函数中调用虚函数


    C++语言规定:在某个类的构造函数(或析构函数)中调用虚函数,执行的是当前构造函数(或析构函数)所属类的虚函数的函数体。

    以代码为例说明问题:

     1 class Point
     2 {
     3 public:
     4     Point(float x = 0,float y = 0)
     5     {
     6         printf("Point::Point() 
    ");
     7         size();
     8     }
     9     virtual void size(){printf("Point::size 
    ");}
    10 };
    11 
    12 class Point3d : public Point
    13 {
    14 public:
    15     Point3d(float x = 0,float y = 0,float z = 0)
    16         :Point(x,y)
    17         {
    18             printf("Point3d::Point3d() 
    ");
    19             size();
    20         }
    21     virtual void size(){printf("Point3d::size 
    ");}
    22 };

    当声明变量时:

     1 Point3d vd; 

    打印结果为:

    1 Point::Point() 
    2 Point::size 
    3 Point3d::Point3d() 
    4 Point3d::size 

    当子类Point3d的构造函数调用基类Point的构造函数时,在基类构造函数内访问虚函数void size()

    实际上执行的是基类中对应的函数体Point::size(),而在子类Point3d中访问虚函数size()时,实际上执行的是子类中对应的函数体Point3d::size()。

    这是因为虚表指针(vptr)的缘故。

    vptr是虚函数指针,指向类的虚函数表。通过vptr找到虚函数表中对应的虚函数,这是C++多态的本质。

    vptr初始化的时机:基类构造函数执行之后,程序员提供的代码或构造函数中初始化列表初始化之前。

    所以才会出现开篇提到的情况。

     

    总结构造函数的执行顺序:

    1. 在派生类的构造函数中,所有的虚基类及基类的构造函数都会被执行。

    2. 对象的虚表指针(一个或多个)被初始化,分别指向对应的虚函数表。

    3. 如果有初始化列表,将在构造函数内扩展开来。这一步是在虚表指针初始化之后执行。

    4. 执行程序员所提供的代码。

     

  • 相关阅读:
    Python爬虫重写。
    python threading
    问题8:手机端实现点击按钮时更换颜色(解决IOS不显示背景)
    问题7:JavaScript 常用正则示例
    常见问题6:控制台报错整理——报错
    常见问题5:图片与文字垂直居中
    bootstrap学习总结
    常见问题4:文本不能选择 效果
    常见问题3:自适应大小高度与宽度
    javascript——10章 DOM
  • 原文地址:https://www.cnblogs.com/calence/p/12663985.html
Copyright © 2020-2023  润新知