#include <iostream>
using namespace std;
/*
* base class
*/
class A
{
public:
A()
{
this->init();
}
virtual void init()
{
cout << " A";
}
// in public, so class B can call it.
void testit()
{
this->init();
}
};
/*
* child class
*/
class B : public A
{
public:
B()
{
this->init();
}
virtual void init()
{
// here get segmentation fault.
// but if call A::init() then it is ok.
A::testit();
// if call A::init(); then it working.
cout << "B" ;
}
};
int main()
{
B b;
A * a = &b;
// here B virtual function will be called.
a->init();
return 0;
}
基本上这是一个虚拟功能测试。但是我发现当子类在其自己的虚函数内调用基类函数时,它会得到运行时分段错误。为什么?
这里运行时因为A :: testit()而出现分段错误 但为什么?
为什么子实例调用基函数会出错?
答案 0 :(得分:1)
// but if call A::init() then it is ok.
A::testit();
您在init()
中呼叫A::testit()
。 init()
是虚拟的,然后B::init()
将在当前实际对象为B
时递归调用,并最终成为无限递归。
如果你明确地调用A::init()
将会避免无限递归,那么它就没问题了。
答案 1 :(得分:1)
简而言之,分段错误是由于无休止的递归造成的。 B::init
调用A::testit
,调用对象的init
。由于该对象属于B
类,这意味着A::testit
将调用B::init
,这将调用A::testit
,依此类推。
为什么这样做而不是明确调用A::init
?嗯,这是多态性的一个例子。在这种情况下,this
内的B::init
指针指向类B
的对象。由于B
已覆盖A
的虚拟init
方法,因此对该对象init
的任何调用都将调用{{1}中的覆盖方法}}。因此B
正在调用B::init()
,它会在无限循环中调用A::testit()
。要拨打父B::init()
的父版本,您必须明确调用它(init
)。