委派构造函数

多个构造函数场景

根据实际开发场景,需要构建多个构造函数,如:

#include <iostream>
class Info
{
public:
	Info()        : m_iType(1), m_szName("q")   {InitRest();}
	Info(int iType)   : m_iType(iType), m_szName("q")   {InitRest();}
	Info(std::string szName) : m_iType(1), m_szName(szName)    {InitRest();}
private:
	void InitRest(){ 
	    std::cout<<"InitRest,iType: "<<m_iType<<", szName: "<<m_szName<<std::endl;
	}
	int m_iType;
	std::string m_szName;
};
int main()
{
    Info objInfo1;       //InitRest,iType: 1, szName: q
    Info objInfo2(10);   //InitRest,iType: 10, szName: q
    Info objInfo3("UT"); //InitRest,iType: q, szName: UT
    return 0;
}

3个构造函数,除了初始化列表不同,其他部分基本相同,重复代码;
C++11标椎后可以在变量声明时初始化参数,减少初始化列表;

class Info
{
public:
	Info()        :   {InitRest();}
	Info(int iType)   : m_iType(iType)   {InitRest();}
	Info(std::string szName) : m_szName(szName)    {InitRest();}
private:
	void InitRest(){}
	int m_iType = 1;
	std::string m_szName = "q";
};

还是存在重复部分;C++11标椎后可以使用委派构造函数达成相同的目的,减少重复代码;

委派构造函数介绍

  • 委派构造函数是在C++11标准对C++构造函数的一项改进。主要是为了减少重复代码和减少程序员写构造函数的时间;
  • C++11的委派构造函数是在构造函数的初始化列表位置进行构造、委派的;
  • 委派构造函数是将构造的任务分派给另外一个构造函数完成;
  • 目标构造函数:被调用的构造函数就是目标构造函数;
  • 委派构造函数:初始化列表中调用其他构造函数的是委派构造函数;
  • 注意:委派构造函数不能直接使用初始化列表初始化成员变量
  • 构造函数不能同时“委派”和使用初始化列表。所以委派构造函数要给变量赋初始值,初始化代码必须写在函数体内;
#include <iostream>
class Info
{
public:
	Info() { InitRest(); }
	Info(int iType) :Info() { m_iType = iType; }    //委派给构造函数Info()
	Info(std::string szName) :Info() { m_szName = szName;}    //委派给构造函数Info()
	//Info() :Info(“UT”) ,m_iType (2){} //编译失败
private:
	void InitRest() {
		std::cout << "InitRest,iType: " << m_iType << ", szName: " << m_szName << std::endl;
	}
	int m_iType = 1;
	std::string m_szName = "q";
};
int main()
{
	Info objInfo1;        //InitRest,iType: 1, szName: q
	Info objInfo2(10);    //InitRest,iType: 1, szName: q
	Info objInfo3("UT");  //InitRest,iType: 1, szName: q
	return 0;
}
  • 你会发现,打印出的内容还是复制之前的内容,这是因为初始化列表的调用优先于构造函数;即先调用了Info();后再调用的赋值语句(m_iType = iType;);这是一个令人容易进入的陷阱,一定要注意;

正确使用委派构造函数

  • 我们通过定义一个私有目标构造函数且将初始化列表放在私有目标构造函数中,这样其他的委派构造函数就可以委托该目标函数来完成构造了。
#include <iostream>
class Info
{
public:
	Info():Info(1,"q") {}
	Info(int iType) :Info(iType,"q") {}    //委派给私有的构造函数Info(int,std::string)
	Info(std::string szName) :Info(1,szName) {}    //委派给私有的构造函数Info(int,std::string)
private:
    Info(int iType,std::string szName) :m_iType (iType),m_szName (szName )
    {
        InitRest();
    }
	void InitRest() {
		std::cout << "InitRest,iType: " << m_iType << ", szName: " << m_szName << std::endl;
	}
	int m_iType;
	std::string m_szName;
};
int main()
{
	Info objInfo1;        //InitRest,iType: 1, szName: q
	Info objInfo2(10);    //InitRest,iType: 10, szName: q
	Info objInfo3("UT");  //InitRest,iType: 1, szName: UT
	return 0;
}
  • **C++11中目标构造函数的执行总是先于委派构造函数。**应该避免目标构造函数和委派构造函数中初始化同样的成员,否则可能得到一项不到的结果。

链状委派构造函数

class Info
{
public:
	Info():Info(1) {}   //Info()是委派构造函数,委派给了Info(int)
	Info(int iType) :Info(iType,"q") {}   //Info(int)既是委派构造函数,委派给了Info(int,std::string);  也是目标构造函数 
	Info(std::string szName) :Info(1,szName) {}           Info()是委派构造函数
private:
    Info(int iType,std::string szName) :m_iType (iType),m_szName (szName ){InitRest(); }    //目标构造函数
	void InitRest() {}
	int m_iType;
	std::string m_szName;
};

链状委托构造: Info()委托Info(int)进行构造,而Info(int)又委托给Info(int,std::string)进行构造。
注意避免形成委托环,形成委托环时,编译器会提示:构造函数直接或间接委托给其自身。
委托环例子:

class Info
{
public:
	Info():Info(1) {}     //Info()委托Info(int)
	Info(int iType) :Info("q") {}   //Info(int)委托Info(std::string)
	Info(std::string szName) :Info(1) {}     //Info(std::string)委托Info(int)   
private:
	int m_iType;
	std::string m_szName;
};

委派构造函数的实际应用

一个很实际的应用:使用构造模板函数产生目标构造函数。

#include <list>
#include <vector>
#include <deque>
class TempleUT
{
public:
	TempleUT(const std::vector<int>& v) :TempleUT(v.begin(), v.end()){}
	TempleUT(const std::deque<int>& d) : TempleUT(d.begin(), d.end()){}
private:
	template<class T>
	TempleUT(T first, T last):l(first, last){}
private:
	std::list<int> l;
};

资料主要源自:深入理解 C++11,C++11新特性解析与应用

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qzy0621

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值