题代码
class A
{
public:
virtual void func(int val = 1){ std::cout << "A->" << val << std::endl; }
virtual void test(){ func(); }
};
class B : public A
{
public:
void func(int val = 0){ std::cout << "B->" << val << std::endl; }
};
int main(int argc, char* argv[])
{
B* p = new B;
p->test();
p->func();
return 0;
}
运行结果:
解释:
第一次的解释:
子类的重写虚函数会覆盖自己虚表中父类对应虚函数的对应虚函数指针,虚表是在代码段,但此时调用的父类中的test()
时,其val
的值为1,所以这个题会先调用子类虚表中对应的虚函数指针,执行该虚函数,但其中调用的 val
还会是父类在栈中保存的值!!!!
第二次的解释:
第一次解释中的说法有点问题,现在更新一下:
虚函数继承是接口继承,普通函数继承是实现继承。所以在调用子类的 func()
时,代码实现用的是子类自己的代码,但由于是虚函数继承,所以这个继承了父类中 func()
的接口,而这个接口中 val = 1
,因此最后除了来的答案是 B->1
而不是 B->0
.