#include <iostream>
using namespace std;
/* 类 Info 1
class Info
{
public:
Info() :type(1), name('a')
{
InitRest();
}
Info(int i) : type(i), name('a')
{
InitRest();
}
Info(char e) : type(1), name(e)
{
InitRest();
}
private:
int type;
char name;
void InitRest(){}
};
*/
//以上 Info()类的代码,是否可以简化呢? 三个构造函数,除了参数和初始化列表不同,函数体都是一样的
//我们可以将一个构造函数设定为 基准版本 ,比如这里的 Info() 版本的构造函数,而其他构造函数可以通过委派 基准版本 来进行初始化
// C++ 11中的委派构造函数,是在构造函数初始化列表位置进行构造和委派的
//我们将上面Info类的代码进行简化
//类 Info 2
/*
class Info
{
public:
Info()//这是 基准版本 的构造函数 称之为 “目标构造函数”
{
InitRest();
}
// 所谓委派构造,就是指委派函数,将构造的任务 委派给了目标构造函数来完成这样一种类构造的方式
Info(int i) : Info() //这个在初始化列表中使用了 基准版本 的构造函数的 构造函数 就称之为 委派构造函数
{
type = i;
}
// 注意:委派构造函数 不能有初始化列表,所以成员变量要赋初值,必须放在函数体里
//Info(char e) :Info(), name(e) //这里报错 error C3511: “Info”: 对委托构造函数的调用应仅为成员初始值设定项
//{
//}
Info(char e) : Info()
{
name = e;
}
void GetType() { cout << "type = " << type << endl; }
private:
int type{ 1 };
char name{ 'a' };
void InitRest(){ type += 1;};
};
*/
// 上面这个简化,委托构造函数无法使用初始化列表,这里会有一个问题,因为初始化列表是先于构造函数完成的,这可能会使程序犯错
// 所以,我们可以稍微改造一下目标构造函数,使得我们的委派构造函数,依然可以在初始化列表中初始化所有成员
// 类 Info 3
/*
class Info
{
public:
Info() : Info(1, 'a'){} //委派构造函数 1
Info(int i) : Info(i, 'a') {} //委派构造函数 2
Info(char e) : Info(1, e){} //委派构造函数 3
void GetType(){ cout << "type = " << type << endl; }
private:
Info(int i, char e) : type(i), name(e)//定义了一个私有的目标构造函数,注意 目标构造函数是先于委派构造函数执行的
{
type += 1;
}
int type;
char name;
};
*/
// 而在构造函数比较多的时候,我们可能不止一个委派构造函数,而一些目标构造函数,也有可能是委派构造函数
// 这样一来,我们就可能在委派构造函数中,形成链状的委派构造关系
// 类 Info 4
struct Info
{
Info() : Info(1) {} //委派构造函数
Info(int i) : Info(i, 'a') {} // 既是委派构造函数,又是目标构造函数
Info(char e) : Info(1, e) {}
void GetType() { cout << "type = " << type << endl; }
private:
Info(int i, char e) : type(i), name(e) // 委派构造函数
{
type += 1;
}
int type;
char name;
};
// 类 Info 4 中, Info() 委派 Info(int) 进行构造, Info(int) 又委派 Info(int, char)进行构造。
// 在委派构造链中,一定要注意不要形成委托环
int main()
{
Info f(3);
f.GetType();// 这里我们分别用 第2种 Info的定义和第3种Info的定义,输出不一样,这就是会导致问题,而我们实际需要的结果是第3种的输出
system("pause");
return 0;
}
注:本篇内容来自于书籍 深入理解C++11 ,如果需要此数,可以留言邮箱地址