By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
428,813 Members | 2,269 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 428,813 IT Pros & Developers. It's quick & easy.

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

P: n/a
what happens if i call a base class virtual function in a derived class constructor?
Oct 26 '10 #1
Share this Question
Share on Google+
2 Replies


P: 1
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.
Oct 29 '10 #2

Banfa
Expert Mod 5K+
P: 8,916
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

Expand|Select|Wrap|Line Numbers
  1.  
  2. #include<iostream>
  3. using namespace std;
  4.  
  5.  
  6. class Base
  7. {
  8. public:
  9.     Base()
  10.     {
  11.         print();
  12.     }
  13.  
  14.     ~Base()
  15.     {
  16.     }
  17.  
  18.     virtual void print()
  19.     {
  20.         cout << "Base : " << name() << endl;
  21.     }
  22.  
  23.     virtual const char *name()
  24.     {
  25.         return "Base";
  26.     }
  27. };
  28.  
  29. class Derived : public Base
  30. {
  31. public:
  32.     Derived()
  33.     {
  34.         print();
  35.     }
  36.  
  37.     ~Derived()
  38.     {
  39.     }
  40.  
  41.     virtual void print()
  42.     {
  43.         cout << "Derived : " << name() << endl;
  44.     }
  45. };
  46.  
  47. class MoreDerived : public Derived
  48. {
  49. public:
  50.     MoreDerived()
  51.     {
  52.         print();
  53.     }
  54.  
  55.     ~MoreDerived()
  56.     {
  57.     }
  58.  
  59.     virtual void print()
  60.     {
  61.         cout << "MoreDerived : " << name() << endl;
  62.     }
  63.  
  64.     virtual const char *name()
  65.     {
  66.         return "MoreDerived";
  67.     }
  68. };
  69.  
  70.  
  71. int main()
  72. {
  73.     MoreDerived md;
  74.     return 0;
  75. }
  76.  
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

Expand|Select|Wrap|Line Numbers
  1. Base : Base
  2. Derived : Base
  3. MoreDerived : MoreDerived
  4.  
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

Expand|Select|Wrap|Line Numbers
  1. class Base
  2. {
  3. public:
  4.     Base()
  5.     {
  6.         print();
  7.     }
  8.  
  9.     ~Base()
  10.     {
  11.     }
  12.  
  13.     virtual void print()
  14.     {
  15.         cout << "Base : " << name() << endl;
  16.     }
  17.  
  18.     virtual const char *name() = 0;
  19. };
  20.  
giving the output

Expand|Select|Wrap|Line Numbers
  1. pure virtual method called
  2. terminate called without an active exception
  3. Aborted
  4.  
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.
Oct 29 '10 #3

Post your reply

Sign in to post your reply or Sign up for a free account.