以下程序输出是什么???
class classA
{
public:
classA()
{
clear();
}
virtual ~classA()
{
}
void clear()
{
memset(this , 0 , sizeof(*this));
}
virtual void func()
{
printf("func\n");
}
};
class classB : public classA
{
};
int main(void)
{
classA oa;
classB ob;
classA * pa0 = &oa;
classA * pa1 = &ob;
classB * pb = &ob;
oa.func(); // 1
ob.func(); // 2
pa0->func(); // 3
pa1->func(); // 4
pb->func(); // 5
return 0;
}
答案:
1.func 2.func 3.执行出错 4.func 5.func
首先memset把基类的对象数据成员改成0。
1和2是通过对象调用,不是通过指针或引用,所以用不到虚指针。能正确调用
3是因为通过指针调用虚函数,但是删除了vptr,调用就失败了
4和5之所以正确能运行,是因为虽然基类删除了vptr,但是派生类构造的时候又更新了vptr,所以4和5都能成功运行。
关于这方面thinking in C++有清晰的叙述