C++ 11 委派构造函数

#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 ,如果需要此数,可以留言邮箱地址

发布了80 篇原创文章 · 获赞 19 · 访问量 2万+

猜你喜欢

转载自blog.csdn.net/qiukapi/article/details/105061248