虚表生成在父类构造完之后,子类构造之前
,生成父类虚表,再执行子类的构造,这时虚表已经重写,可以多态(即开始派生类构造初始化列表代码)。
验证:输出This is animal miao miao miao
1
#include<iostream>
using std::cout;
using std::cin;
using std::endl;
struct Animal
{
virtual int callOut()const
{
cout << "This is animal ";
return 0;
}
Animal()
{
callOut();
}
};
class Cat:public Animal
{
virtual int callOut()const
{
cout << "miao miao miao" << endl;
return 1;
}
int a;
public:
Cat():a(callOut())
{
cout << a << endl;
}
};
int main()
{
const Animal& cat = Cat();
return 0;
}
//错题
class A
{
public:
A ():m_iVal(0){test();}
virtual void func() { std::cout<<m_iVal<<‘ ’;}
void test(){func();}
public:
int m_iVal;
};
class B : public A
{
public:
B(){test();}
virtual void func()
{
++m_iVal;
std::cout<<m_iVal<<‘ ’;
}
};
int main(int argc ,char* argv[])
{
A*p = new B;
p->test();
return 0;
}
运行结果:0,1,2
分析:new B时先调用父类A的构造函数,执行test()函数,在调用func()函数,由于此时还处于对象构造阶段,多态机制还没有生效,所以,此时执行的func函数为父类的func函数,打印0,构造完父类后执行子类构造函数,又调用test函数,然后又执行func(),由于父类已经构造完毕,虚表已经生成,func满足多态的条件,所以调用子类的func函数,对成员m_iVal加1,进行打印,所以打印1, 最终通过父类指针p->test(),也是执行子类的func,所以会增加m_iVal的值,最终打印2, 所以答案为C 0 1 2