C++ 学习基础十八——在构造(析构)函数中调用虚函数
C++语言规定:在某个类的构造函数(或析构函数)中调用虚函数,执行的是当前构造函数(或析构函数)所属类的虚函数的函数体。
以代码为例说明问题:
1 class Point 2 { 3 public: 4 Point(float x = 0,float y = 0) 5 { 6 printf("Point::Point() \n"); 7 size(); 8 } 9 virtual void size(){printf("Point::size \n");} 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() \n"); 19 size(); 20 } 21 virtual void size(){printf("Point3d::size \n");} 22 };
当声明变量时:
1 Point3d vd;
打印结果为:
1 Point::Point() 2 Point::size 3 Point3d::Point3d() 4 Point3d::size
vptr
是虚函数指针,指向类的虚函数表。通过vptr找到虚函数表中对应的虚函数,这是C++多态的本质。
vptr初始化的时机:基类构造函数执行之后,程序员提供的代码或构造函数中初始化列表初始化之前。
所以才会出现开篇提到的情况。
总结构造函数的执行顺序:
1. 在派生类的构造函数中,所有的虚基类及基类的构造函数都会被执行。
2. 对象的虚表指针(一个或多个)被初始化,分别指向对应的虚函数表。
3. 如果有初始化列表,将在构造函数内扩展开来。这一步是在虚表指针初始化之后执行。
4. 执行程序员所提供的代码。