what happens if i call a base class virtual function in a derived class constructor?

Collapse
X
 
  • Time
  • Show
Clear All
new posts
  • RAVISEKHAR

    #1

    what happens if i call a base class virtual function in a derived class constructor?

    what happens if i call a base class virtual function in a derived class constructor?
  • stelarobinson
    New Member
    • Oct 2010
    • 1

    #2
    When constructing the derived class, the base class is constructed first. If you call a virtual method from the base class constructor, the overridden method is called. But notice that when that overridden method is called, the derived class is not initialized because its constructor code was not executed yet.

    Comment

    • Banfa
      Recognized Expert Expert
      • Feb 2006
      • 9067

      #3
      If you call a virtual function from a base class then you will call the function in the base class because the vtable is filled in as the class hierarchy is constructed and that is constructed from base class to derived class.

      This code demonstrates that

      Code:
      #include<iostream>
      using namespace std;
      
      
      class Base
      {
      public:
          Base()
          {
              print();
          }
      
          ~Base()
          {
          }
      
          virtual void print()
          {
              cout << "Base : " << name() << endl;
          }
      
          virtual const char *name()
          {
              return "Base";
          }
      };
      
      class Derived : public Base
      {
      public:
          Derived()
          {
              print();
          }
      
          ~Derived()
          {
          }
      
          virtual void print()
          {
              cout << "Derived : " << name() << endl;
          }
      };
      
      class MoreDerived : public Derived
      {
      public:
          MoreDerived()
          {
              print();
          }
      
          ~MoreDerived()
          {
          }
      
          virtual void print()
          {
              cout << "MoreDerived : " << name() << endl;
          }
      
          virtual const char *name()
          {
              return "MoreDerived";
          }
      };
      
      
      int main()
      {
          MoreDerived md;
          return 0;
      }
      showing that as MoreDerived goes though the stages of constructing Base then Derived then MoreDerived caused by the instantiation in main, it calls virtual functions from each of the classes in question as the class is built up from its inherited components giving the output

      Code:
      Base : Base
      Derived : Base
      MoreDerived : MoreDerived
      So when calling a virtual function from a base constructor it is using the base classes vtable and calls the base method not the method of the class being constructed.

      So this means that if you call a virtual function from a constructor the intended function call may not take place if the class is used as a base for another class.

      Worst still if the function is pure virtual in the class calling it then you will dereference a NULL pointer and cause a crash which can be demonstrated by changing Base in my example to

      Code:
      class Base
      {
      public:
          Base()
          {
              print();
          }
      
          ~Base()
          {
          }
      
          virtual void print()
          {
              cout << "Base : " << name() << endl;
          }
      
          virtual const char *name() = 0;
      };
      giving the output

      Code:
      pure virtual method called
      terminate called without an active exception
      Aborted
      You can never be absolutely sure someone wont derive from your class so ...

      For these reasons calling a virtual function from a constructor is considered bad practice and calling one from a destructor is generally worst.

      Your compiler may be able to warn you about this and static analysis tools like lint certainly can.

      Comment

      Working...