Chapter 5. Semantics of Construction, Destruction, and Copy
5.1 “無(wú)繼承” 情況下的對(duì)象構(gòu)造
1. 普通類(lèi)型(和C相同)
2. 抽相數(shù)據(jù)類(lèi)型
3. 為繼承作準(zhǔn)備
5.2 繼承體系下對(duì)象的構(gòu)造
1.? 通用繼承構(gòu)造規(guī)則
???? (1) 在成員初始化列表中的data members初始化操作會(huì)被放進(jìn)constructor的函數(shù)本身,并以members的聲明順序?yàn)轫樞颉?br />???? (2) 如果有一個(gè)member沒(méi)有出現(xiàn)在初始化列表中,但它有一個(gè)default constructor,那么default constructor會(huì)被調(diào)用。
???? (3) 如果class object 有virtual table pointer(s), 它(們)必須被設(shè)定初始值,指向適當(dāng)?shù)膙irtual table(s)。
???? (4) 在那之前,所有的上一層的base class constructors必須被調(diào)用, 以base class的聲明順序?yàn)轫樞?br />???? (5) 在那之前,所有的virtual base class constructors必須被調(diào)用,從左到右,從最深到最淺。
2. 虛擬繼承(virtual Inheritance)
如對(duì)于下面的類(lèi):?
?1?
class?Point3d?:?public?virtual?Point
?2?
?{?
?3?
?public:?
?4?
????Point3d(?float?x?=?0.0,?float?y?=?0.0,?float?z?=?0.0?)?
?5?
????????:?Point(?x,?y?),?_z(?z?)?{}?
?6?
????Point3d(?const?Point3d&?rhs?)?
?7?
????????:?Point(?rhs?),?_z(?rhs._z?)?{}?
?8?
????~Point3d();?
?9?
????Point3d&?operator=(?const?Point3d&?);?
10?
11?
????virtual?float?z(){?return?_z;?}?
12?
????//?
?
13?
?protected:?
14?
????float?_z;?
15?
?};?
?
?可能的轉(zhuǎn)換是這樣的:
?1?//?Psuedo?C++?Code:?
?2??//?Constructor?Augmentation?with?Virtual?Base?class?
?3??Point3d*?Point3d::Point3d(?Point3d?*this,?bool?__most_derived,??float?x,?float?y,?float?z?)?
?4??{?
?5???if?(?__most_derived?!=?false?)?
?6????this->Point::Point(?x,?y);?
?7?
?8???this->__vptr__Point3d?=?__vtbl__Point3d;?
?9???this->__vptr__Point3d__Point?=?__vtbl__Point3d__Point;?
10?
11???this->_z?=?rhs._z;?
12???return?this;?
13??}?
?//
?對(duì)于如下的繼承層次:
?class Vertex?? : virtual public Point { ... };
?class Vertex3d : public Point3d, public Vertex { ... };
?class PVertex? : public Vertex3d { ... };
?類(lèi)Point3d的構(gòu)造可能是:
?1?//?Psuedo?C++?Code:?
?2??//?Constructor?Augmentation?with?Virtual?Base?class?
?3??Point3d*?Point3d::Point3d(?Point3d?*this,?bool?__most_derived,??float?x,?float?y,?float?z?)?
?4??{?
?5???if?(?__most_derived?!=?false?)?
?6????this->Point::Point(?x,?y);?
?7?
?8???this->__vptr__Point3d?=?__vtbl__Point3d;?
?9???this->__vptr__Point3d__Point?=?__vtbl__Point3d__Point;?
10?
11????this->_z?=?rhs._z;?
12???return?this;?
13??}
?//
?對(duì)于Vertex3d的構(gòu)造可能是如下:
?1?//?Psuedo?C++?Code:?
?2??//?Constructor?Augmentation?with?Virtual?Base?class?
?3??Vertex3d*?Vertex3d::Vertex3d(?Vertex3d?*this,?bool?__most_derived,?float?x,?float?y,?float?z?)?
?4??{?
?5???if?(?__most_derived?!=?false?)?
?6????this->Point::Point(?x,?y);?
?7?
?8???//?invoke?immediate?base?classes,?
?9???//?setting?__most_derived?to?false?
10?
11???this->Point3d::Point3d(?false,?x,?y,?z?);?
12???this->Vertex::Vertex(?false,?x,?y?);?
13?
14???//?set?vptrs?
15???//?insert?user?code?
16?
17???return?this;?
18??}?
?
3. vptr初始化語(yǔ)意學(xué)(The Semantics of the vptr Initialization)
???? (1) 構(gòu)造函數(shù)執(zhí)行算法
????????? I.??? 在derived class constructor 中, 所有的"virtual base classes" 及 "上一層base class"的constructors會(huì)被調(diào)用.
?? II.? 上述完成之后, 對(duì)象的vptr(s)會(huì)被初始化, 指向相關(guān)的virtual talbe(s).
?? III. 如果有成員初始化列表的話(huà), 將在constructor體內(nèi)擴(kuò)展開(kāi)來(lái). 這必須在vptr被設(shè)定之后才能進(jìn)行,以免有一個(gè)virtual member function被調(diào)用
?? IV. 最后, 執(zhí)行程序所提供的代碼.
????
???? (2) 示例:
???? For example, given the following user-defined PVertex constructor:
1?PVertex::PVertex(?float?x,?float?y,?float?z?)?
2?????:?_next(?0?),?Vertex3d(?x,?y,?z?)
3?????,?Point(?x,?y?)?
4??{?
5???if?(?spyOn?)?
6????cerr?<<?"within?Point3d::Point3d()"??<<?"?size:?"?<<?size()?<<?endl;?
7??}?
?
??可能一個(gè)擴(kuò)展如下:
?1?//?Pseudo?C++?Code?
?2??//?expansion?of?PVertex?constructor?
?3??PVertex*?PVertex::PVertex(?Pvertex*?this,??bool?__most_derived,?float?x,?float?y,?float?z?)?
?4??{?
?5???//?conditionally?invoke?the?virtual?base?constructor?
?6???if?(?__most_derived?!=?false?)?
?7????this->Point::Point(?x,?y?);?
?8???//?unconditional?invocation?of?immediate?base?
?9????this->Vertex3d::Vertex3d(?x,?y,?z?);?
10?
11???//?initialize?associated?vptrs?
12?
13???this->__vptr__PVertex?=?__vtbl__PVertex;?
14???this->__vptr__Point__PVertex?=?__vtbl__Point__PVertex;?
15?
16???//?explicit?user?code?
17???if?(?spyOn?)?
18????cerr?<<?"within?Point3d::Point3d()"?
19????<<?"?size:?"?<<?(*this->__vptr__PVertex[?3?].faddr)(this)?
20????<<?endl;?
21?
22???//?return?constructed?object?
23???return?this;?
24??}?
?
5.3 對(duì)象的復(fù)制(Object Copy Sematics)
1. Copy constructor operator 在以下幾種情況下不會(huì)表現(xiàn)出: bitwisecopy
???? (1) class 內(nèi)帶有一個(gè)member object, 而其類(lèi)有一個(gè)copy constructor operator時(shí)。
???? (2)? 當(dāng)一個(gè) class 的base 有一個(gè)copy assignment operator時(shí)。
???? (3)? 當(dāng)類(lèi)聲明了任何一個(gè)virtual functions時(shí)。
???? (4)? 當(dāng)class繼承自一個(gè)virtual base class時(shí)
?2. 合成示例
?1??//?Pseudo?C++?Code:?synthesized?copy?assignment?operator?
?2??inline?Point3d&?Point3d::operator=(?Point3d?*const?this,?const?Point3d?&p?)?
?3??{?
?4???//?invoke?the?base?class?instance?
?5???this->Point::operator=(?p?);?
?6?
?7???//?memberwise?copy?the?derived?class?members?
?8???_z?=?p._z;?
?9???return?*this;?
10??}?
?
5.4 對(duì)象的功能
5.5 析構(gòu)語(yǔ)意學(xué)(Semantics of Destruction)
1. 析構(gòu)函數(shù)生成原則:
?如果類(lèi)沒(méi)有定義destructor, 那么只有在class內(nèi)帶的member object(或是class自己的base class)擁有destructor的情況下,編譯器才會(huì)自動(dòng)的合成一個(gè)來(lái)。否則,destructor會(huì)被視為不需要,也就不需要被合成(當(dāng)然更不需要被調(diào)用)
2. 析構(gòu)調(diào)用過(guò)程
???? (1) destructor的函數(shù)本身首先被執(zhí)行。
???? (2) 如果class擁有member class objects, 而后者擁有destructors, 那么它會(huì)以其聲明順序的相反順序被調(diào)用.
???? (3) 如果object內(nèi)帶一個(gè)vptr, 則現(xiàn)在被重新設(shè)定,指向適當(dāng)?shù)腷ase class的virtual table.
???? (4) 如果任何直接的(上一層)novirtual base classes 擁有destructor,那么它會(huì)以其聲明順序相反的順序調(diào)用
???? (5) 如果有任何的virtual base classes 擁有destructor, 而當(dāng)前討論的這個(gè)class是最末端的class, 那么它們會(huì)以其原來(lái)的構(gòu)造順序相反的順序被調(diào)用.
?