C++11 委托构造函数

1.简介

委托构造函数(Delegating Constructor)由 C++11 引入,是对 C++ 构造函数的改进,允许构造函数通过初始化列表调用同一个类的其他构造函数,目的是简化构造函数的书写,提高代码的可维护性,避免代码冗余膨胀。

通俗来讲,一个委托构造函数使用它所属的类的其他构造函数执行自己的初始化过程,或者说它把自己的一些(或者全部)职责委托给了其他构造函数。和其他构造函数一样,一个委托构造函数也有一个成员初始化列表和一个函数体,成员初始化列表只能包含一个其它构造函数,不能再包含其它成员变量的初始化,且参数列表必须与构造函数匹配。

首先看一下一个不使用委托构造函数造成代码冗余的例子。

class Foo
{
public:
	Foo() :type(4), name('x') {initRest();}
	Foo(int i) : type(i), name('x') {initRest();}
	Foo(char c) :type(4), name(c) {initRest();}

private:
	void initRest() {/* init othre members */}
	int type;
	char name;
	//...
};

从上面的代码片段可以看出,类Foo的三个构造函数除了参数不同,初始化列表、函数体基本相同,其代码存在着很多重复。在C++11中,我们可以使用委托构造函数来减少代码重复,精简构造函数。

class Foo
{
public:
    Foo() {initRest(); }
    Foo(int i) : Foo() {type = i;}
    Foo(char e) : Foo() {name = e;}
private:
    void initRest() { /* init othre members */}
    int type{1};
    char name{'a'};
};

一个委托构造函数想要委托另一个构造函数,那么被委托的构造函数应该包含较大数量的参数,初始化较多的成员变量。而且在委托其他构造函数后,不能再进行成员列表初始化,而只能在函数体内对其他成员变量进行赋值。

2.注意事项

(1)不要形成委托环。
在构造函数较多的时候,我们可能拥有多个委托构造函数,而一些目标构造函数很可能也是委托构造函数,这样依赖,我们就可能在委托构造函数中形成链状的委托构造关系,形成委托坏(Delegation Cycle)。

class Foo
{
public:
	Foo(int i) : Foo('c') { type = i; }
	Foo(char c) : Foo(1) { name = c; }
private:
	int type;
	char name;
};

其中 Foo(int i) 与 Foo(char c) 相互委托就形成了委托坏,这样会导致编译错误。

(2)如果在委托构造函数中使用 try,可以捕获目标构造函数中抛出的异常。

#include <iostream> 
using namespace std;

class Foo
{
public:
	Foo(int i) try: Foo(i,'c') 
	{
		cout<<"start assignment"<<endl;
		type = i; 
	}
	catch(...)
	{
		cout<<"caugth exception"<<endl;
	}

private:
	Foo(int i,char c) 
	{
		cout<<"throw exception"<<endl;
		throw 0;
	}
	int type;
	char name;

};

int main()
{
	Foo f(1);
	return 0;
}

程序输出结果:

throw exception
caugth exception

可见在目表构造函数 Foo(int i,char c) 中抛出异常,在委托构造函数Foo(int i) 中可以进行捕获,并且目标构造函数体内的代码并不会被执行。这样的设计是合理的,因为目标构造函数抛出异常说明对象并没有完成初始化,在委托构造函数中进行赋值操作都是一些无意义的动作。


参考文献

[1] Stanley B. Lippman等著,王刚,杨巨峰译.C++ Primer 中文第5版[M].北京:电子工业出版社,2013-09-01
[2] Michael Wong, IBM XL编译器中国开发团队.深入理解C++11[M].北京:机械工业出版社,2013-06-01
[3] 关于使用C++11中委托构造函数

©️2020 CSDN 皮肤主题: 编程工作室 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值