C++ 委托构造函数

1. 委托构造函数的使用场景

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// 场景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;
};
// 场景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; };
// 场景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;
};

缺点:每个构造函数都有重复的成员变量的初始化语句

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
// 场景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;
};
// 场景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; };
// 场景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;
};

初始化交给一个普通成员函数,该成员函数无法使用简洁的初始化列表语句,需要额外给类增加一个初始化函数。

2. 委托构造函数语法

C++11 增加了委托构造函数,委托构造函数也叫做委派构造函数,指的是,将当前构造函数的初始化任务交给其他的构造函数来完成。

委托构造函数使用的一般步骤是什么?

  1. 先找一个能够将所有的成员变量进行初始化的构造函数、或者更加通用的构造函数,当做【目标构造函数】目标构造函数实际是执行初始化任务的构造函数。
  2. 将其他的构造函数的初始化任务交由该目标函数进行初始化。

委托构造函数的优点:代码更加清晰、构造函数的行为更加正确

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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;
}
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; }
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;
}

3. 委托构造函数使用注意

  1. 委托构造函数不能同时使用目标构造函数、初始化列表对对象进行初始化。原因:初始化列表执行先于构造函数。如果目标构造函数和初始化列表同时初始化同一个变量,可能造成问题。非委托构造函数可以使用初始化列表。
  2. 不允许委托多个目标构造函数执行初始化任务,委托构造函数委托的目标构造函数能够进行完整初始化。
  3. 委托构造函数可以将初始化任务交给另外一个委托构造函数,但是要注意不能出现闭环。

注意事项一的示例代码:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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 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 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;
};

注意事项二的示例代码:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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 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 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;
};

注意事项三的示例代码:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
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;
};
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; };
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;
};
未经允许不得转载:一亩三分地 » C++ 委托构造函数
评论 (0)

9 + 3 =