Should I call the base class default constructor in the initialization list?

18,368

Solution 1

The base class constructor is called in both cases.

Here is a link to an article with more info.

Solution 2

If the base class constructor doesn't take any argument, then explicit mention of it in the initialization list is not needed.

Solution 3

If B doesn't have a user declared constructor, the behavior is different. Compare:

struct SimpleAggregate {
  int a;
  float b;
};

struct ClassWrapper : SimpleAggregate {
  ClassWrapper() : SimpleAggregate() { }
};

ClassWrapper w;

Now, w.a and w.b are guaranteed to be zero. If you would have left off the explicit initialization of the base class, they would have indeterminate values.


It may be unknown to you that, despite the syntax, the above use of SimpleAggregate() does not call the default constructor, though. It simply value initializes the base class (we have several good answers here on Stackoverflow about what "value initialization" is), not calling the default constructor because there is none user declared.

Solution 4

To complete the learning experience and develop deeper understanding, you could start to modify things slightly. For instance, what happens when B has no default constructor? Does it even compile? Other slight modifications like this will provide a great learning experience.

That said, in my experience it's generally better to do this

A::A() : B() { ... } 

than

A::A() { ... } 

because the former is more explicit, and it will get you to think about what's really going on with base class initialization. You will probably avoid hidden behavior by spelling out things explicitly.

Solution 5

Every class that is derived from some other class must call the base class' constructor. A derived class can only be constructed once all base class' are fully constructed. So it doesn't matter if you call the base class' constructor or not. If you don't call, as long as there is a default constructor available for compiler to determine, it will be called. Otherwise compiler will throw error.

Share:
18,368

Related videos on Youtube

q0987
Author by

q0987

Updated on June 06, 2020

Comments

  • q0987
    q0987 about 4 years
    class A : public B
    {
      ...
    }
    
    // case I : explicitly call the base class default constructor
    A::A() : B()
    {
      ...
    }
    
    // case II : don't call the base class default constructor
    A::A() // : B()
    {
      ...
    }
    

    Is the case II equal to case I?

    To me, I assume that the default constructor of base class B is NOT called in case II. However, despite still holding this assumption, I have run a test which proves otherwise:

    class B
    {
    public:
        B()
        {
            cout << "B constructor" << endl;
        }
    };
    
    class A : public B
    {
    public:
        A()
        {
            cout << "A constructor" << endl;
        }
    };
    
    int _tmain(int argc, _TCHAR* argv[])
    {
        A a;
        return 0;
    }
    

    // output from VS2008

    B constructor
    A constructor
    Press any key to continue . . .
    
  • Krythic
    Krythic over 9 years
    I gave you a plus one because you suggested ways to improve ones understanding of this topic.
  • Pete Forman
    Pete Forman over 7 years
    I have given +1 because this answers the question "should ...". Most of the other answers are for the related question "must ...".
  • bartgol
    bartgol over 3 years
    This is such a big difference. This one should be accepted as the answer.