admin管理员组文章数量:1572314
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:
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;
}
};
|
本文标签: ProcessEasyIllustrate
版权声明:本文标题:process is actually easy to illustrate 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://www.elefans.com/xitong/1725880139a1046753.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论