C++构造函数之委托构造函数
今天在讀《C++Primer》時(shí)讀到委托構(gòu)造函數(shù)一節(jié),書中關(guān)于委托構(gòu)造函數(shù)是這樣描述的:
一個(gè)委托構(gòu)造函數(shù)使用它所屬的類的其他構(gòu)造函數(shù)執(zhí)行自己的初始化過程,或者說它把自己的一些(或者全部)職責(zé)委托給了其他構(gòu)造函數(shù)。和其他構(gòu)造函數(shù)一樣,一個(gè)委托構(gòu)造函數(shù)也有一個(gè)成員初始值的列表和一個(gè)函數(shù)體。在委托構(gòu)造函數(shù)內(nèi),成員的初始值列表只有一個(gè)唯一的入口,就是類名本身。和其他成員初始值一樣,類名后面緊跟圓括號(hào)括起來的參數(shù)列表,參數(shù)列表必須與類中另外一個(gè)構(gòu)造函數(shù)匹配。
初讀這段話,可能理解上有一些偏差,一開始覺得意思就是一個(gè)構(gòu)造函數(shù)可以用其他構(gòu)造函數(shù)。于是寫了段測(cè)試代碼:
? ? class A
? ? {
? ? ? ? private:
? ? ? ? ? ? int a;
? ? ? ? ? ? char c;
? ? ? ? public:
? ? ? ? ? ? A(int num):a(num){}
? ? ? ? ? ? A(char C):c(C){}
? ? ? ? ? ? A(int num,char C):A(num),A(C){}//調(diào)用其他兩個(gè)構(gòu)造函數(shù)
? ? };
示例化一個(gè)對(duì)象x:A x(0,'x')
編譯不過,提示錯(cuò)誤:
error:mem-initializer for ‘class A’ follows constructor delegation A(int num,char C):A(num),A(C){}
成員初始化失敗!StackOverFlow上也有人遇到了這個(gè)問題,有人給出了解答:
When you delegate the member initialization to another constructor, there is an assumption that the other constructor initializes the object completely, including all members. You can’t therefore initialize any of the members again.
意思大概是當(dāng)你委托另一個(gè)構(gòu)造函數(shù)時(shí),假定這個(gè)構(gòu)造函數(shù)可以完整地構(gòu)造出這個(gè)對(duì)象。上面的無論是A(int num)還是A(char C)都不能完整地構(gòu)造出對(duì)象。按照這個(gè)思路,改一下代碼如下:
? ? class A
? ? {
? ? ? ? private:
? ? ? ? ? ? int a;
? ? ? ? ? ? char c;
? ? ? ? public:
? ? ? ? ? ? A(int num,char C):a(num),c(C){}
? ? ? ? ? ? A(int num):A(num,' '){}//給char c默認(rèn)值
? ? };
這下代碼可以編譯通過了。那么是否真的這樣呢?再用一段測(cè)試代碼:
? ? class A
? ? {
? ? ? ? private:
? ? ? ? ? ? int a;
? ? ? ? ? ? int b;
? ? ? ? ? ? char c;
? ? ? ? ? ? //char d;
? ? ? ? public:
? ? ? ? ? ? A(int num0,int num1,char C):a(num0),b(num1),c(C){}
? ? ? ? ? ? A(int num0,char C):A(num0,0,C){}//委托上一個(gè)構(gòu)造函數(shù)
? ? ? ? ? ? A(int num0):A(num0,' '){} ? ? ? //委托上一個(gè)構(gòu)造函數(shù)?
? ? };
代碼編譯通過,注意到這里第二個(gè)構(gòu)造函數(shù)委托第一個(gè)構(gòu)造函數(shù),能完整地構(gòu)造出對(duì)象;而第三個(gè)構(gòu)造函數(shù)委托第二個(gè)函數(shù),也能完整地構(gòu)造出對(duì)象。如果第一個(gè)構(gòu)造函數(shù)不能完整地構(gòu)造出對(duì)象,結(jié)果是什么樣呢?把上面對(duì)char d的注釋去掉,發(fā)現(xiàn)代碼也能編譯通過,d有默認(rèn)值空!!!
那么StackOverFollow上的解答就是有誤的,被委托的構(gòu)造函數(shù)并不用包含所有成員變量,只要包含最大數(shù)量的成員變量即可。關(guān)于stackoverflow上的解答請(qǐng)點(diǎn)這里。
不過,我發(fā)現(xiàn)答主后面補(bǔ)充了一下:
As a general rule, you should fully specify that version of the constructor that takes the largest number of arguments, and then delegate from the other versions (using the desired default values as arguments in the delegation).
普遍規(guī)則是被委托的構(gòu)造函數(shù)應(yīng)該包含最大數(shù)量的參數(shù),然后被其他構(gòu)造函數(shù)委托(可以使用默認(rèn)值進(jìn)行委托構(gòu)造)~
了解到在使用委托構(gòu)造函數(shù)時(shí),不能再進(jìn)行成員列表初始化,而只能在函數(shù)體內(nèi)進(jìn)行初始化其他成員變量。那么我們?cè)谖衅渌麡?gòu)造函數(shù)構(gòu)造對(duì)象時(shí),一些成員變量以默認(rèn)值構(gòu)造了,在函數(shù)體內(nèi)進(jìn)行初始化就不叫初始化了,只能叫重新賦值了。見下面例子:
?class A
? {
? ? ? private:
? ? ? ? ? int a;
? ? ? ? ? int b;
? ? ? ? ? char c;
? ? ? ? ? char d;
? ? ? public:
? ? ? ? ? A(int num0,int num1,char C):a(num0),b(num1),c(C){}
? ? ? ? ? A(int num0,char C):A(num0,0,C){}//b默認(rèn)初始化為0
? ? ? ? ? A(int num0):A(num0,'p'){b=1;}//b重新賦值為1
? ? ? ? ? void getMembers()
? ? ? ? ? {
? ? ? ? ? ? ? cout<<a<<" "<<b<<" "<<c<<" "<<d<<endl;
? ? ? ? ? }
? };
在委托第二個(gè)構(gòu)造函數(shù)構(gòu)造時(shí),b被初始化為0,這里我們?cè)诤瘮?shù)體內(nèi)重新賦值為1,那么b到底是0還是1呢?結(jié)果是1。函數(shù)體內(nèi)的初始化要晚于成員列表初始化,即委托其他構(gòu)造函數(shù)構(gòu)造完后,在進(jìn)行函數(shù)體內(nèi)的賦值。
總結(jié)
一個(gè)構(gòu)造函數(shù)想要委托另一個(gè)構(gòu)造函數(shù),那么被委托的構(gòu)造函數(shù)應(yīng)該包含較大數(shù)量的參數(shù),初始化較多的成員變量。而且在委托其他構(gòu)造函數(shù)后,不能再進(jìn)行成員列表初始化,而只能在函數(shù)體內(nèi)進(jìn)行初始化其他成員變量。
————————————————
版權(quán)聲明:本文為CSDN博主「赤道以北」的原創(chuàng)文章,遵循 CC 4.0 BY-SA 版權(quán)協(xié)議,轉(zhuǎn)載請(qǐng)附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/huangtiao2509/article/details/73882305
總結(jié)
以上是生活随笔為你收集整理的C++构造函数之委托构造函数的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何用emacs打开许多文件
- 下一篇: C++中的值初始化和默认初始化