zoukankan      html  css  js  c++  java
  • 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. 执行程序员所提供的代码。

     

  • 相关阅读:
    PTA数据结构与算法题目集(中文) 7-6
    PTA数据结构与算法题目集(中文) 7-5
    PTA数据结构与算法题目集(中文) 7-4
    PTA数据结构与算法题目集(中文) 7-3
    数据结构学习第二十三天
    数据结构学习第二十三天
    数据结构学习第二十二天
    数据结构学习第二十一天
    数据结构学习第二十天
    并发之ATOMIC原子操作--CAS乐观锁原理(二)
  • 原文地址:https://www.cnblogs.com/calence/p/12663985.html
Copyright © 2011-2022 走看看