虚函数给出分段错误的原因

时间:2016-07-13 02:55:41

标签: c++ segmentation-fault runtime-error virtual-functions

#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()而出现分段错误 但为什么?

为什么子实例调用基函数会出错?

2 个答案:

答案 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)。