C++類(lèi)中一個(gè)構(gòu)造函數(shù)調(diào)用另一個(gè)構(gòu)造函數(shù)
class?A??
{??
????int?a;??
????int?b;??
????int?c;??
public:??
????A(int?aa,?int?bb)?:?a(aa),?b(bb),c(0)??{?cout?<<?"aa?bb"?<<?endl;?}??
????A(int?aa,?int?bb,?int?cc);??
};??
上面類(lèi)中,已經(jīng)有一個(gè)構(gòu)造函數(shù),形參有兩個(gè),我們又重載一個(gè)有3個(gè)形參的構(gòu)造函數(shù),為了減少代碼量,就想著讓3個(gè)參數(shù)的構(gòu)造函數(shù)調(diào)用2個(gè)參數(shù)的構(gòu)造函數(shù),然后在執(zhí)行一些自己的代碼,這就如同派生類(lèi)先調(diào)用基類(lèi)的同名函數(shù),在執(zhí)行自己特有的代碼。這種機(jī)制如何實(shí)現(xiàn)呢?
做法一:在3個(gè)參數(shù)中顯示調(diào)用2個(gè)參數(shù)的構(gòu)造函數(shù)(這肯定是可以的, 構(gòu)造函數(shù)是類(lèi)的成員函數(shù)),此時(shí)要用到placement new技術(shù)。
3參數(shù)構(gòu)造函數(shù)可以這樣實(shí)現(xiàn):
[cpp]?view plain?copy ?A::A(int?aa,?int?bb,?int?cc)??? {?? ????new?(this)?A(aa,?bb);?? ????...?? }?? 構(gòu)造函數(shù)有2個(gè)執(zhí)行階段:1)是在初始化列表的初始化階段;2)在構(gòu)造函數(shù)體內(nèi)的賦值階段。上述方法是在第二個(gè)階段。placement new技術(shù)的形式是 new(void *p) Type(...),表示在p所指的內(nèi)存區(qū)域調(diào)用Type構(gòu)造函數(shù),該過(guò)程沒(méi)有內(nèi)存請(qǐng)求。上述實(shí)現(xiàn)有“投機(jī)取巧”之嫌,就是在對(duì)象地址處,調(diào)用2個(gè)參數(shù)的構(gòu)造函數(shù)重新生成一個(gè)新的對(duì)象然后覆蓋該對(duì)象。
做法二:在VS2013中發(fā)現(xiàn)可以在構(gòu)造函數(shù)初始化列表直接調(diào)用,類(lèi)似于調(diào)用基類(lèi)構(gòu)造函數(shù)。該方法在g++中不適合。
[cpp]?view plain?copy ?A::A(int?aa,?int?bb,?int?cc)?:A(aa,?bb)?? {?? ????...?? }?? 上述說(shuō)了構(gòu)造函數(shù)有2個(gè)執(zhí)行階段,該方法是在第一個(gè)階段進(jìn)行的,這種方式有點(diǎn)類(lèi)似C#里面的機(jī)制,更加方便。該方法有個(gè)注意事項(xiàng)是不能在A(aa, bb)后面在接c(cc)了,因?yàn)檎{(diào)用2個(gè)參數(shù)的構(gòu)造函數(shù)之后,就相當(dāng)于該對(duì)象已經(jīng)初始化完成了,不能在初始化列表放入其他成員的初始化形式。只能放在構(gòu)造函數(shù)體中的賦值階段。該方法目前只能用在VS2013中。
做法二有很大的局限性,不過(guò)確實(shí)很方便。不知標(biāo)準(zhǔn)文檔對(duì)于構(gòu)造函數(shù)互相調(diào)用有怎樣的規(guī)定?是否以后其他編譯器會(huì)加入該功能?