1
2
3
4
5
6
7
8
9
10
11
|
class
Derived:
public
Base
{
public
:
double
m_dValue;
Derived(
double
dValue=0.0,
int
nValue=0)
: m_dValue(dValue)
{
m_nValue = nValue;
}
};
|
而这其实是在这种情况下,它不会工作,如果m_nvalue是const或引用(const值和引用,因为必须在构造函数初始化列表初始化)。这也是因为m_nvalue低效得到分配一个值的两倍:一旦在基类构造函数的初始化列表,然后再在派生类的构造函数体。
那么我们如何正确初始化m_nvalue当创建派生类对象?
在所有的例子到目前为止,当我们实例化一个派生类对象的基类部分,已使用默认构造函数创建的基础。为什么它总是使用默认基类构造函数?因为我们从来没有告诉它做否则!
幸运的是,C + +让我们能够明确地选择哪个基类构造函数会被调用!要做到这一点,只需添加一个电话在派生类的基类构造函数初始化列表:
1
2
3
4
5
6
7
8
9
10
11
|
class
Derived:
public
Base
{
public
:
double
m_dValue;
Derived(
double
dValue=0.0,
int
nValue=0)
: Base(nValue),
// Call Base(int) constructor with value nValue!
m_dValue(dValue)
{
}
};
|
Now, when we execute this code:
1
2
3
4
5
6
|
int
main()
{
Derived cDerived(1.3, 5);
// use Derived(double) constructor
return
0;
}
|
基类构造函数的基地(int)将被用来初始化m_nvalue 5,和派生类的构造函数来初始化m_dvalue 1.3!
在更多的细节,这里会发生什么事情:
内存分配cderived。
派生(double,int)调用构造函数,其中值= 1.3,和值= 5
编译器查看我们所要求的特定基类的构造函数。我们有,因此,呼叫基地(int)与N值= 5。
基类构造函数的初始化列表设置m_nvalue 5
基类构造函数体执行
基类构造函数返回
派生类的构造初始化列表设置m_dvalue 1.3
派生类的构造函数体执行
派生类的构造函数返回
这看起来可能有点复杂,但其实很简单。所有发生的一切都是派生构造函数调用一个特定基类构造函数初始化对象的基类部分。因为m_nvalue生活在对象的基类部分,基构造函数是唯一的构造函数,可以初始化它的价值。