- 委托构造函数的使用场景 {#title-0} =========================
// 场景1
class Box1
{
public:
Box1() : m_l(0), m_h(0), m_w(0) {}
Box1(int l) : m_l(l), m_h(0), m_w(0) {}
Box1(int l, int h) : m_l(l), m_h(h), m_w(0) {}
Box1(int l, int h, int w) : m_l(l), m_h(h), m_w(w) {}
public:
int m_l;
int m_h;
int m_w;
};
缺点:每个构造函数都有重复的成员变量的初始化语句
// 场景2
class Box2
{
public:
Box2()
{
init(0, 0, 0);
}
Box2(int l)
{
init(l, 0, 0);
}
Box2(int l, int h)
{
init(l, h, 0);
}
Box2(int l, int h, int w)
{
init(l, h, w);
}
// 初始化函数
void init(int l, int h, int w)
{
m_l = l;
m_h = h;
m_w = w;
}
public:
int m_l;
int m_h;
int m_w;
};
初始化交给一个普通成员函数,该成员函数无法使用简洁的初始化列表语句,需要额外给类增加一个初始化函数。
- 委托构造函数语法 {#title-1} ======================
C++11 增加了委托构造函数,委托构造函数也叫做委派构造函数,指的是,将当前构造函数的初始化任务交给其他的构造函数来完成。
委托构造函数使用的一般步骤是什么?
- 先找一个能够将所有的成员变量进行初始化的构造函数、或者更加通用的构造函数,当做【目标构造函数】目标构造函数实际是执行初始化任务的构造函数。
- 将其他的构造函数的初始化任务交由该目标函数进行初始化。
委托构造函数的优点:代码更加清晰、构造函数的行为更加正确
class Box3
{
public:
// 前三个构造函数,叫做委托构造函数
Box3() : Box3(0, 0, 0)
{
cout << "委托构造函数 Box3()" << endl;
}
Box3(int l) : Box3(l, 0, 0)
{
cout << "委托构造函数 Box3(int l)" << endl;
}
Box3(int l, int h) : Box3(l, h, 0)
{
cout << "委托构造函数Box3(int l, int h) " << endl;
}
// 目标构造函数
Box3(int l, int h, int w) : m_l(l), m_h(h), m_w(w)
{
cout << "目标构造函数" << endl;
}
public:
int m_l;
int m_h;
int m_w;
};
void test01()
{
// 当调用一个委托构造函数进行对象构建时,其构造函数调用的顺序是什么?
// 首先,调用目标构造函数进行初始化
// 然后,再调用委托构造函数本身进行初始化
Box3 box;
}
-
委托构造函数使用注意 {#title-2} ========================
-
委托构造函数不能同时使用目标构造函数、初始化列表对对象进行初始化。原因:初始化列表执行先于构造函数。如果目标构造函数和初始化列表同时初始化同一个变量,可能造成问题。非委托构造函数可以使用初始化列表。
-
不允许委托多个目标构造函数执行初始化任务,委托构造函数委托的目标构造函数能够进行完整初始化。
-
委托构造函数可以将初始化任务交给另外一个委托构造函数,但是要注意不能出现闭环。
注意事项一的示例代码:
class Box4
{
public:
// 前三个构造函数,叫做委托构造函数
// Box4() : Box4(0, 0, 0), m_l(100) { }
Box4(int l) : Box4(l, 0, 0) {}
Box4(int l, int h) : Box4(l, h, 0) {}
// 目标构造函数
Box4(int l, int h, int w) : m_l(l), m_h(h), m_w(w) {}
public:
int m_l;
int m_h;
int m_w;
};
注意事项二的示例代码:
class Box5
{
public:
// 以下注释代码编译错误
// Box5(int l, int h, int w) : Box5(l), Box5(h, w){}
Box5(int l) : m_l(l) {}
Box5(int h, int w) : m_h(h), m_w(w) {}
public:
int m_l;
int m_h;
int m_w;
};
注意事项三的示例代码:
class Box6
{
public:
// 一定要注意:避免出现委托构造链表的闭环
//Box6() : Box6(0){ }
//Box6(int l) : Box6(l, 0) {}
//Box6(int l, int h) : Box6(l, h, 0) {}
//Box6(int l, int h, int w) : Box6(){}
public:
int m_l;
int m_h;
int m_w;
};