开发者

Inheritance - the Instantiation problem

In Inheritance, when a derived class is instantiated (derived class obj created) then first memory is set aside. After this the derived class constructor is called.

class Base
    {
    public:
        int m;   
开发者_高级运维        Base(int x=0)
            : m(x)
        {
        }
    };

    class Derived: public Base
    {
    public:
        double n;

            Derived(double y=0.0)   
            : n(y)
            {
        }
    };

In the above example, when create derived class object, derived class constructor is called.

The problem is, from what I studied, the base class constructor is called before the derived class constructor is called. But, there is no explicit instruction anywhere in the derived class to first go to the base class constructor. How does the complier know that base class constructor has to be executed first ????

I thought the answer would be this line in the declaration of base class :

class Derived: public Base

But, the problem is by changing the derived class as follows we can make sure Base class constructor is called and initialized before derived constructor body executes.

class Derived: public Base
    {
    public:
        double n;

            Derived(double y=0.0, int z=0)   
            : Base(z), n(y)
            {
        }
    };

So, the issue is that in the first example there was no statement to tell the base class constructor to be called first, yet it is actually called first, in the second altered example I tell the compiler to goto base class constructor first. Doesn't it already know to goto base class constructor first?? What is the difference in execution between the 2 examples and what are the steps?

Regards,


The compiler knows to call the Base class constructor because you have specified that you are inheriting Base via the statement:

class Derived : public Base

No matter what, the compiler is going to instantiate (i.e. call the constructor) of the Base class prior to calling the constructor of Derived. It has too in order to properly construct the derived class.

In the second example where you state: Base(z) in your initialization list, you're telling the compiler to explicitly call/initialize the Base class with this constructor. When you don't specify a constructor via the initialization list, the compiler will always call the default constructor. Specifying the correct constructor in the initialization list (even when it is the default) is considered best practice.


If you have a Ball and you derive a RedBall from it then to create a RedBall the first thing you need is a Ball, then you can paint it red.

So, to create an Object of type Derived in your example, you need to start with an object of type Base then construct the Derived from it. So even when you do not explicitly call the base class' constructor the compiler knows it has to. The line

 class Derived: public Base

actually is the instruction that informs the compiler of this.

In the second case you are being explicit about it. This can be used in the case where you want to call a constructor of the base class that has poarameters say.


In first example you call default constructor. In second example you call constructor with parametar


What is the difference in execution between the 2 examples and what are the steps?

The difference is, that in first case DEFAULT constructor will be called, while in second case, one that you have been chosen.


I think the misconception is that the C++ language is somehow step-by-step interpreted, otherwise I can't explain the "willn't the compiler already have called base class constructor and initialized it before it sees the call in derived class constructor ".

This is not the case, basically the compiler "sees" all the compilation unit before it begins to generate the output. If it sees that you've made an explicit call to one particular constructor - via Base(z) in your case it will call that one when creating your Derived object. Otherwise it will call the default constructor for Base.

It would probably be better not to declare your base constructor as Base(int x = 0). Try creating both a parameter-less constructor and the Base(int) one and put a breakpoint in each to see exactly which one is called. (alternatively, put a breakpoint in Base(int x = 0) and check the value of x...)

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜