class AA
{
public:
AA(int a= 0)
{
this->a = a;
print(); //在构造函数里面能实现多态吗?
}
virtual void print()
{
cout<<"父类的"<<"a"<<a<<endl;
}
protected:
int a ;
};
class BB : public AA
{
public:
BB(int a= 0, int b = 0)
{
this->a = a;
this->b = b;
}
virtual void print()
{
cout<<"子类的"<<"a"<<a<<"b"<<b<<endl;
}
private:
int b ;
};
void howToPrintf(AA *pBase)
{
pBase->print();
{
BB b1;
howToPrintf(&b1);
{
public:
AA(int a= 0)
{
this->a = a;
print(); //在构造函数里面能实现多态吗?
}
virtual void print()
{
cout<<"父类的"<<"a"<<a<<endl;
}
protected:
int a ;
};
class BB : public AA
{
public:
BB(int a= 0, int b = 0)
{
this->a = a;
this->b = b;
}
virtual void print()
{
cout<<"子类的"<<"a"<<a<<"b"<<b<<endl;
}
private:
int b ;
};
void howToPrintf(AA *pBase)
{
pBase->print();
}
{
BB b1;
howToPrintf(&b1);
}
结果:输出"父类的a";而不是"子类ab".
解释:子类vptr指针的初始化过程是分步完成的。
1、当指向父类的构造函数的时候,如果你在父类的构造函数里面调用虚函数,C++编译会初始化子类的vptr指针,让vptr指针指向父类的虚函数表;
2、当父类的构造函数执行完毕后,再执行子类的构造函数,这个时候,让vptr指针真正的指向子类的虚函数表。
总结:
(1)对象在创建的时,由编译器对VPTR指针进行初始化
(2)只有当对象的构造完全结束后VPTR的指向才最终确定
(3)父类对象的VPTR指向父类虚函数表
(4)子类对象的VPTR指向子类虚函数表