trickletree
trickletree

Reputation: 21

why virtual function give segmentation fault

#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; 

}

Basically this is a virtual function test. But I found when child class call base class function inside its own virtual function, it get runtime segmentation fault. why?

here when run time it get segmentation fault since at A::testit() but why?

why child instance call base function get error?

Upvotes: 1

Views: 4406

Answers (2)

Bettorun
Bettorun

Reputation: 227

In short, the segmentation fault is due to endless recursion. B::init calls A::testit, which calls the object's init. Since the object is of class B, this means that A::testit will call B::init, which will call A::testit, and so on endlessly.

Why does it do this and not call A::init explicitly? Well, it's a case of polymorphism. In this situation, the this pointer inside of B::init points towards an object of class B. Since B has overwritten A's virtual init method, any calls to that object's init will be calling the overwritten method in B. So B::init() is calling A::testit(), which calls B::init() in an endless loop. To call the parent's version of init, you have to call it explicitly (A::init).

Upvotes: 1

songyuanyao
songyuanyao

Reputation: 172854

// but if call A::init() then it is ok. 
A::testit();

You're calling init() in A::testit(). init() is virtual, then B::init() will be called recursively when the current actual object is B, and becomes infinite recursion at last.

If you call A::init() explicitly infinite recursion will be avoided then it'll be ok.

Upvotes: 1

Related Questions