C++11 统一初始化(Uniform Initialization)
1 統(tǒng)一初始化(Uniform Initialization)
在C++ 11之前,所有對(duì)象的初始化方式是不同的,經(jīng)常讓寫代碼的我們感到困惑。C++ 11努力創(chuàng)造一個(gè)統(tǒng)一的初始化方式。
其語(yǔ)法是使用{}和std::initializer_list,先看示例。
2 原理
針對(duì)形如"{ 1, 2, 3 }"的參數(shù)列表,系統(tǒng)會(huì)首先自動(dòng)調(diào)用參數(shù)初始化(value initialization),將其轉(zhuǎn)換成一個(gè)std::initializer_list,它將用于對(duì)變量(可能是簡(jiǎn)單類型,或者對(duì)象類型)初始化。比如"{ 1, 2, 3 }"會(huì)首先生成一個(gè)std::initializer_list,然后用于生成一個(gè)int數(shù)組values。c{4.0, 3.0}會(huì)生成一個(gè)std::initializer_list,然后調(diào)用std::comples類的構(gòu)造函數(shù)std::comples(double,double)。
我們通過(guò)一個(gè)例子來(lái)分析具體細(xì)節(jié):
- 首先,將參數(shù)列表{ 2, 3, 6, 7 }轉(zhuǎn)換成std::initializer_list。
從stl源碼中可以看出initializer_list的帶參數(shù)構(gòu)造函數(shù)是個(gè)私有函數(shù),它只能由編譯器調(diào)用。
- 其次,使用std::initializer_list對(duì)象來(lái)初始化std::vector類的構(gòu)造函數(shù)。下面是構(gòu)造函數(shù)源碼。 vector(initializer_list<value_type> __l,const allocator_type& __a = allocator_type()): _Base(__a){_M_range_initialize(__l.begin(), __l.end(),random_access_iterator_tag());}
3 未賦值的初始化
如果使用了std::initializer_list,但是沒有指定參數(shù)值,結(jié)果會(huì)怎樣?直接看示例。
int i; //i值未定義int j{}; //j=0int *p; //p值未定義int *q{}; //q=nullptr4 在構(gòu)造函數(shù)中顯示使用std::initializer_list
我們可以在構(gòu)造函數(shù)中主動(dòng)使用std::initializer_list,這時(shí)外部調(diào)用{}初始化時(shí),會(huì)優(yōu)先調(diào)用包含std::initializer_list參數(shù)的構(gòu)造函數(shù)。請(qǐng)看下例子。
class P{public:P(int, int){std::cout<<"call P::P(int,int)"<<std::endl;}P(std::initializer_list<int>){std::cout<<"call P::P(initializer_list)"<<std::endl;}};P p(77,5); // call P::P(int,int)P q{77,5}; // call P::P(initializer_list)P r{77,5,42}; // call P::P(initializer_list)P s = {77, 5}; // call P::P(initializer_list)5 拒絕隱式調(diào)用構(gòu)造函數(shù)
我們知道,C++會(huì)先使用{}中的參數(shù)生成一個(gè)std::initializer_list對(duì)象,然后調(diào)用賦值對(duì)象的構(gòu)造函數(shù)。
class P{public:P(int a, int b){...}explicit P(int a, int b, int c){...}};P x(77,5); //OKP y{77,5}; //OKP z{77,5,42}; //OKp v = {77,5}; //OK,(implicit type conversion allowed)P w = {77,5,42};//Error,必須要顯示調(diào)用該構(gòu)造函數(shù)void fp(const P&);fp({47,11}); //OKfp({47,11,3}); //Errorfp(P{47,11}); //OKfp(P{47,11,3}); //OK
有一種特殊情形,我們?nèi)绻M麑?duì)象的某個(gè)構(gòu)造函數(shù)必須要被顯示調(diào)用,如何做到呢?向其中添加一個(gè)explicit關(guān)鍵字。在stl庫(kù)中出現(xiàn)大量的這種使用方式。請(qǐng)看下例:6 局限 —— Narrowing Initializations
統(tǒng)一初始化用起來(lái)很舒爽,那它有什么局限呢?
有,在一種場(chǎng)景下無(wú)法使用,那就是Narrowing Initializations。
Narrowing Initializations,我翻譯為“精度截?cái)唷薄1热鏵loat轉(zhuǎn)換為int,double轉(zhuǎn)換為float。統(tǒng)一初始化,完全不允許精度階段的發(fā)生,更進(jìn)一步,要求參數(shù)列表中的所有參數(shù)的精度一樣。請(qǐng)看以下示例。
但是如果實(shí)際工程允許精度截?cái)嗟陌l(fā)生,那么我們應(yīng)該怎么完成初始化。可以使用()來(lái)完成初始化,它會(huì)調(diào)用賦值操作或者相應(yīng)的構(gòu)造函數(shù)。
int x3{5.0}; //Errorint x2(5.2); //OK, x2 = 5總結(jié)
以上是生活随笔為你收集整理的C++11 统一初始化(Uniform Initialization)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 英国富时100实时指数
- 下一篇: 全国城市创新能力百强榜揭晓!北上深前三