《深度探索C++对象模型》--5 构造析构拷贝 6 执行期语意学
《深度探索C++對(duì)象模型》--5構(gòu)造、析構(gòu)、拷貝語意學(xué)
1、純虛函數(shù):
(1)C++可以定義和調(diào)用一個(gè)純虛函數(shù),不過只可以靜態(tài)調(diào)用,不可以由虛擬機(jī)制調(diào)用。
注意:pure virtual destructor一定得定義,因?yàn)槊恳粋€(gè)derivedclass destructor會(huì)被編譯器加以擴(kuò)張,以靜態(tài)方式調(diào)用其每一個(gè)virtual base class及上一個(gè)base class的destructor,如果缺乏任何一個(gè)base class destructor的定義就會(huì)導(dǎo)致鏈接失敗。
綜上,不要把virtual destructor聲明為pure。
(2)如果一個(gè)函數(shù)定義內(nèi)容并不與類型有關(guān),幾乎不會(huì)被后續(xù)的derived class改寫,則沒有必要聲明為virtual。
(3)virtual函數(shù)最好不要加const。
2、“無繼承”情況下的對(duì)象構(gòu)造
(1)Plain OL' Data具有trivialcopy等操作,編譯器實(shí)際上不會(huì)產(chǎn)生。
(2)explicit initialization list的缺點(diǎn):
只有當(dāng)class members都是public,才有效;只能指定常量,因?yàn)樵诰幾g期間就可以被評(píng)估求值;由于編譯器沒有自動(dòng)實(shí)施,初始化行為的失敗率要高一些。
(3)如果許多函數(shù)需要以傳值方式傳回一個(gè)local class object,則提供一個(gè)copy constructor合理,觸發(fā)NRV優(yōu)化。
3、繼承體系下的對(duì)象構(gòu)造
constructor的執(zhí)行算法:
在derived class constructor中,所有virtual baseclasses以及上層base class的constructors都會(huì)被調(diào)用;
上述完成后,對(duì)象的vptr被初始化,指向相關(guān)的virtual table;
如果有member initialization list的話,將在constructor體內(nèi)擴(kuò)展開來。這必須在vptr被設(shè)定之后才做,以免有一個(gè)virtual member function被調(diào)用;
最后執(zhí)行體內(nèi)所提供的代碼。
4、對(duì)象復(fù)制語意學(xué)
(1)只有在默認(rèn)行為不安全或者不正確時(shí),才設(shè)計(jì)一個(gè)copy assignmentoperator。可能自己提供一個(gè),來打開NRV優(yōu)化。
(2)盡可能地不要允許一個(gè)virtualbase class的拷貝操作。建議不要在任何virtual base class中聲明數(shù)據(jù)。
5、析構(gòu)語意學(xué)
析構(gòu)過程與constructor順序相反。
?
《深度探索C++對(duì)象模型》--6執(zhí)行期語意學(xué)
C++的困難之一,就是不容易從代碼看出來表達(dá)式的復(fù)雜,一個(gè)類似if(yy == xx.getValue())的簡(jiǎn)單式子,有可能經(jīng)歷操作符重載,轉(zhuǎn)換運(yùn)算符-》if(yy.operator == ( xx.getValue.operator Y() ));這些都由編譯器暗中進(jìn)行。
1、對(duì)象的構(gòu)造和析構(gòu)
(1)把object盡可能放置在使用它的那個(gè)程序區(qū)段附近,以節(jié)省不必要的產(chǎn)生對(duì)象和銷毀操作。
(2)C++程序中所有的globalobject都被放置在程序的datasegment中(其它的應(yīng)該是在heap或stack中)。如果明確的給一個(gè)值,object將以該值為初值。否則object所配置的內(nèi)存內(nèi)容為0。
2、new和delete運(yùn)算符
(1)語言要求每一次對(duì)new的調(diào)用都必須傳回一個(gè)獨(dú)一無二的指針,傳統(tǒng)方法就是傳回一個(gè)指針,指向一個(gè)默認(rèn)為1-Byte的內(nèi)存區(qū)塊。
(2)注意,如果用的當(dāng)一個(gè)baseclass指針指向一個(gè)derivedclass objects所組成的數(shù)組時(shí),delete時(shí)只會(huì)調(diào)用base class的destructor,虛擬機(jī)制不起作用,如下:
Point * pointer = new Point3d[10];delete [ ] pointer;//此時(shí)調(diào)用的是Point::~Point()
如果必須這樣做的話必須迭代走過整個(gè)數(shù)組,把delete實(shí)施于每一個(gè)元素上,如此才會(huì)調(diào)用virtual,如下:
for ( int ix=0; ix < elem_count; ++ix ){Point3d *p = &( (Point3d*) ptr ) [ ix ];delete p;}
(3)placementoperator new的語意
Point2w*pt2 = new(arena)Point2w;
其中arena指向內(nèi)存中的一個(gè)區(qū)塊,用以放置新產(chǎn)生出來的Point2w object。
placementoperator new的價(jià)值在于它所擴(kuò)充的另一半是將Point2wconstructor自動(dòng)調(diào)用于arena所指的地址上。注意placement operator new并不支持多態(tài),如Point2s*ptw = new (arena)Point3w;將會(huì)導(dǎo)致嚴(yán)重的破壞。
3、臨時(shí)性對(duì)象
(1)臨時(shí)性對(duì)象的被摧毀,應(yīng)該是對(duì)完整表達(dá)式求值過程中最后的一步。該完整表達(dá)式造成臨時(shí)對(duì)象的產(chǎn)生。
(2)凡持有表達(dá)式執(zhí)行結(jié)果的臨時(shí)性對(duì)象,應(yīng)該存留到object的初始化操作完成為止。
(3)如果一個(gè)臨時(shí)對(duì)象被綁定于一個(gè)reference,對(duì)象將殘留,知道初始化之reference的聲明結(jié)束,或者直到臨時(shí)對(duì)象的聲明范疇結(jié)束。
總結(jié)
以上是生活随笔為你收集整理的《深度探索C++对象模型》--5 构造析构拷贝 6 执行期语意学的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《深度探索C++对象模型》--4 Fun
- 下一篇: 面试题整理 2:求链表倒数第 k 个结点