构造函数中调用虚函数,能实现多态吗?
内容来源: 传智播客
c++面试中常常会问到一个问题:
通过子类对象,在父类构造函数中调用虚函数,能实现多态吗?
#iinclude<iostream> using namespace std; class A { public: int a; A(int a) { this->a = a; print(); } virtual void print() { cout << "执行基类成员函数" << endl; cout << a << endl; } }; class B :public A { public: int b; B(int a, int b) :A(a) { this->b = b; print(); } virtual void print() { cout << "执行子类成员函数" << endl; cout << b <<endl; } }; int main() { B b(1, 2); }
通过上述代码,上述问题转化成: 通过B类生成对象b,在初始化时,需要调用构造函数,根据构造函数的调用规则,需要先调用父类A的构造函数,但是父类构造函数中有虚函数print, 这时他到底会调用父类的print函数, 还是会调用子类的构造函数(多态)
明确上述问题,,需要知道对象中VPTR指针的指向问题,

当定义一个子类对象的时候比较麻烦,因为构造子类对象的时候会首先调用父类的构造函数然后再调用子类的构造函数。当调用父类的构造函数的时候,此时会创建Vptr指针(也可以认为Vptr指针是属于父类的成员,所以在子类中重写虚函数的时候virtual关键字可以省略,因为编译器会识别父类有虚函数,然后就会生成Vptr指针变量),该指针会指向父类的虚函数表;然后再调用子类的构造函数,此时Vptr又被赋值指向子类的虚函数表。
(执行父类的构造函数的时候Vptr指针指向的是父类的虚函数表,所以只能执行父类的虚函数)
上面的过程是Vptr指针初始化的过程。
这是因为这个原因,在构造函数中调用虚函数不能实现多态。

浙公网安备 33010602011771号