在父类的构造函数中调用虚函数是不能够实现多态的,这个问题涉及到vptr指针的初始化问题。
比如在构造子类对象c时,执行到父类的构造函数时,这个c.vptr指向的是父类的虚函数表,这时调用虚函数,执行的是父类的虚函数,不是多态。当执行完父类的构造函数,执行到子类的构造函数时,这个c.vptr指针这时才指向本身自己的虚函数表。注意,每一个对象都有一个vptr指针和一个虚函数表,这个是在编译时就提前布局了,而不是在运行时。
1)对象中的VPTR指针什么时候被初始化?
对象在创建的时,由编译器对VPTR指针进行初始化 只有当对象的构造完全结束后VPTR的指向才最终确定 父类对象的VPTR指向父类虚函数表 子类对象的VPTR指向子类虚函数表
|
2)分析过程 画图分析 |
具体看如下,代码输出:
#include <iostream>
using namespace std;
//构造函数中调用虚函数能发生多态吗?
class Parent
{
public:
Parent(int a=0)
{
this->a = a;
print(); //这个调用的是父类的print函数,无多态发生
}
virtual void print()
{
cout<<"我是爹"<<endl;
}
private:
int a;
};
class Child : public Parent
{
public:
Child(int a = 0, int b=0):Parent(a)
{
this->b = b;
print(); //这个执行的是子类的print函数,有多态发生
}
virtual void print()
{
cout<<"我是儿子"<<endl;
}
private:
int b;
};
void HowToPlay(Parent *base)
{
base->print(); //有多态发生 //2 动手脚
}
void main()
{
Child c1; //定义一个子类对象 ,在这个过程中,在父类构造函数中调用虚函数print 能发生多态吗?
//c1.print();
cout<<"hello..."<<endl;
system("pause");
return ;
}