process is actually easy to illustrate

本文深入探讨了在C++中派生类的构造顺序及其背后的逻辑,通过实例展示了派生类如何首先构造基类部分,然后是派生类部分,并解释了这种构造顺序的重要性。

In the previous lesson on basic inheritance in C++, you learned that classes can inherit members and functions from other classes. In this lesson, we’re going to take a closer look at the order of construction that happens when a derived class is instantiated.

First, let’s introduce some new classes that will help us illustrate some important points.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Base
{
public :
     int m_nValue;
 
     Base( int nValue=0)
         : m_nValue(nValue)
     {
     }
};
 
class Derived: public Base
{
public :
     double m_dValue;
 
     Derived( double dValue=0.0)
         : m_dValue(dValue)
     {
     }
};

In this example, Derived is derived from Base. Because Derived inherits functions and variables from Base, it is convenient to think of Derived as a two part class: one part Derived, and one part Base.

You’ve already seen plenty examples of what happens when we instantiate a normal (non-derived) class:

1
2
3
4
5
6
int main()
{
     Base cBase;
 
     return 0;
}

Base is a non-derived class because it does not inherit from anybody. C++ allocates memory for Base, then calls Base’s default constructor to do the initialization.

Now let’s take a look at what happens when we instantiate a derived class:

1
2
3
4
5
6
int main()
{
     Derived cDerived;
 
     return 0;
}

If you were to try this yourself, you wouldn’t notice any difference from the previous example where we instantiate the non-derived class. But behind the scenes, things are slightly different. As mentioned, Derived is really two parts: a Base part, and a Derived part. When C++ constructs derived objects, it does so in pieces, starting with the base portion of the class. Once that is complete, it then walks through the inheritance tree and constructs each derived portion of the class.

So what actually happens in this example is that the Base portion of Derived is constructed first. Once the Base portion is finished, the Derived portion is constructed. At this point, there are no more derived classes, so we are done.

This process is actually easy to illustrate.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include <iostream>
using namespace std;
 
class Base
{
public :
     int m_nValue;
 
     Base( int nValue=0)
         : m_nValue(nValue)
     {
         cout << "Base" << endl;
     }
};
 
class Derived: public Base
{
public :
     double m_dValue;
 
     Derived( double dValue=0.0)
         : m_dValue(dValue)
     {
         cout << "Derived" << endl;
     }
};
 
int main()
{
     cout << "Instantiating Base" << endl;
     Base cBase;
 
     cout << "Instantiating Derived" << endl;
     Derived cDerived;
 
     return 0;
}

This program produces the following result:

Instantiating Base
Base
Instantiating Derived
Base
Derived

As you can see, when we constructed Derived, the Base portion of Derived got constructed first. This makes sense: logically, a child can not exist without a parent. It’s also the safe way to do things: the child class often uses variables and functions from the parent, but the parent class knows nothing about the child. Instantiating the parent class first ensures those variables are already initialized by the time the derived class is created and ready to use them.

Order of construction for inheritance chains

It is sometimes the case that classes are derived from other classes, which are themselves derived from other classes. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
class A
{
public :
     A()
     {
         cout << "A" << endl;
     }
};
 
class B: public A
{
public :
     B()
     {
         cout << "B" << endl;
     }
};
 
class C: public B
{
public :
     C()
     {
         cout << "C" << endl;
     }
};
 
class D: public C
{
public :
     D()
     {
         cout << "D" << endl;
     }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值