简体   繁体   中英

C++ inheritance initializer list

I am very new to C++ , but I come from a Java background so I understand most of the OOP concepts. I am reading through an introductory guide and I came across this example:

[Foo.H] 
class A
{
    public:
       A(int something);
};

class B : public A
{
    public:
       B(int something);
};

[Foo.C] 
#include "Foo.H"

A::A(int something)
{
    printf("Something = %d\n", something);
}

B::B(int something) : A(something)
{
}

Is it correct to assume that by passing A(something) to the initializer list of B::B(int something) it is similar to the super keyword in java -- aka, it will execute A::A(int something) 's code? Also, why do I only call A(something) instead of A::A(something) from the initalizer list?

Basically I am asking: is the above equivalent to this:

B::B(int something)
{
    A::A(something)
}

Let me expand why I am confused.

If I were to use:

B::B(int something) : A(something)
{
    int x = 5;
    printf("x = %d", x);
}

And call the code via

B::B(7);

Would this print out x = 5 or something = 7 first? And why would it execute in this order?

I am just a little confused as to the syntax which is making it hard to grasp and visualize the inheritance happening in even this simple example.

Yes, A(something) passes that value much like super . You don't have to use A::A because the language automatically injects the base class name into the child class.

It's not however equivalent to

B::B(int something)
{
    A::A(something)
}

because that's not legal code. You can only select which parent constructor to call in the initializer list.

As for your question about printing...did you try it? You'll see that the parent something= prints first followed by x= .

no they are not equivalent

constructor of subclass will call the default constructor of their parent unless you explicitly tell it otherwise in the initializer list.

B::B( int something ) {} will call A::A() implicitly and if A does not have a default constructor it will not compile.

B::B(int something)
{
    A::A(something)
}

what this does is that it tries to call A::A() implicitly in the initializer list, then call A::A(something) , as you know it will not compile given A does not have default constructor.

so if you want to call different parent constructor the only way is to do it is in the initializer list namely

B::B(int something) : A(something) {}
A::A(int something)
{
    printf("Something = %d\n", something);
}

This is the constructor for B. The first thing a constructor does is construct it's base classes (in the order declared in the class, not in the order of the constructor), and then construct the member objects (in the order declared in the class, not in the order of the constructor), and then it executes the body (the code in {} ). The reason it does this is because a B is an A object, so it must be a complete A before it can even start to be a B object. And all members must be fully constructed before executing any member function's code, or else bad things could happen. So both base classes and members must be constructed before the constructor body can begin.

If you want to change how a base class or member is initialized (to pass an integer instead of default constructing for instance), you may put it in the initializer list:

B::B(int something) : A(something)
{
    int x = 5;
    printf("x = %d", x);
}

You don't have to qualify the name of A 's constructor, because we're already in the context of the object B , and B already knows about A .

B::B(int something)
{
    A::A(something)
}

This code is invalid, because B will construct it's A object before executing the body in {} . Since A was already constructed, calling A::A in the body makes no sense, and the compiler will diagnose this.

B::B(int something) : A(something)
{
    int x = 5;
    printf("x = %d", x);
}

As mentioned before, when constructing B, it constructs the base classes first, then members, then executes the body. Therefore you will see

something = 7
x = 5

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM