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