構(gòu)造、析構(gòu)、拷貝語意學(xué)
來源:程序員人生 發(fā)布時(shí)間:2015-03-18 09:35:29 閱讀次數(shù):3070次
對(duì)象的構(gòu)造
無繼承下的對(duì)象構(gòu)造
引子
下面是1個(gè)定義類對(duì)象的例子:
Point global;
Point foobar()
{
Point local;
Point *heap = new Point;
*heap = local;
delete heap;
return local;
}
在上面的例子中,存在3種對(duì)象:全局對(duì)象、局部對(duì)象、堆對(duì)象;這些對(duì)象的生命周期是該對(duì)象的履行期屬性。全局對(duì)象的生命周期從定義開始到程序結(jié)束;局部對(duì)象的生命周期是從定義開始到局部作用域的終止;堆對(duì)象的生命周期是從new
創(chuàng)建該對(duì)象開始到delete
該對(duì)象;
下面根據(jù)Point
類的不同聲明會(huì)表現(xiàn)出不同的行動(dòng):
與C兼容的 Plain Old Data(POD)類型:
在 POD 類型中類Point
聲明以下:
typedef struct{
float x, y, z;
}Point;
在 POD 類型中,對(duì)象的定義不會(huì)調(diào)用 constructor 和 destructor;由于對(duì)象沒有顯示的初始化操作;
抽象數(shù)據(jù)類型(ADT)
在 ADT 類型中類Point
聲明以下:
class Point{
public:
Point(float x = 0.0, float y = 0.0, float z = 0.0)
:_x(x), _y(y), _z(z)
{}
private:
float _x, _y, _z;
}Point;
在 ADT 類型中,創(chuàng)建對(duì)象時(shí)編譯器會(huì)調(diào)用顯示定義的構(gòu)造函數(shù);
繼承體系下的對(duì)象構(gòu)造
繼承體系下構(gòu)造函數(shù)的調(diào)用時(shí),編譯器會(huì)根據(jù)繼承的情況進(jìn)行以下的擴(kuò)充操作:
- member initialization list 中的 data member 會(huì)在構(gòu)造函數(shù)本體中進(jìn)程初始化操作,并以 members 的聲明順序進(jìn)行;
- 若某個(gè) member 沒有在 member initialization list 中,但是該 member 存在 default constructor,則該 member 的 default constructor 會(huì)被調(diào)用;
- 若 class object 存在 virtual table pointer(vptr),則必須設(shè)置 vptr 的初值,使其指向適當(dāng)?shù)?virtual table;
- base class constructors 都會(huì)被調(diào)用,調(diào)用順序?yàn)?base class 的聲明順序;
- 若 base class 在 member initialization list 中,則任何顯示指定的參數(shù)都應(yīng)當(dāng)傳遞過去;
- 若 base class 不在 member initialization list 中,且 base class 存在 default constructor,則會(huì)調(diào)用該 default constructor;
- 若 base class 是多重繼承下的第2或后繼的 base class,則需調(diào)劑 this 指針;
- 所有 virtual base class constructors 都會(huì)被調(diào)用,從左到右,從深到淺:
- 若 class 在 member initialization list 中,則任何顯示指定的參數(shù)都應(yīng)當(dāng)傳遞過去;若 class 不在 member initialization list 中,且 class 存在 default constructor,則會(huì)調(diào)用該 default constructor;
- class 中的每個(gè) virtual base class subobject 的偏移位置必須在履行期可被存取;
- 若 class object 是最底層的 class,其 constructor 可能會(huì)被調(diào)用;
對(duì)象的復(fù)制語意學(xué)
1個(gè) class 在以下情況會(huì)合成默許的 從copy assignment operator:
- 當(dāng) class 內(nèi)含1個(gè)具有 copy assignment operator 的 member object;
- 當(dāng) class 繼承自1個(gè)具有 copy assignment operator 的 base class;
- 當(dāng) class 聲明有 virtual functions;
- 當(dāng) class 派生自 virtual base class(es);
對(duì)象析構(gòu)語意學(xué)
只有在 class 內(nèi)含1個(gè)具有 destructor 的 member class 時(shí),編譯器才會(huì)自動(dòng)合成1個(gè) destructor。
由程序員定義的 destructor 被擴(kuò)大的方式類似構(gòu)造函數(shù)被擴(kuò)大的方式,但是順序相反:
- 如果對(duì)象內(nèi)帶1個(gè) vptr,那末首先重設(shè)相干的virtual table;
- 析構(gòu)的函數(shù)本體現(xiàn)在被履行,也就是說 vptr 會(huì)在程序員的代碼履行前被重設(shè);
- 如果類具有成員類對(duì)象,且該成員類對(duì)象具有析構(gòu)函數(shù),那末他們會(huì)以其聲明順序的相反順序被調(diào)用;
- 如果有任何直接的非虛基類具有析構(gòu)函數(shù),他們會(huì)以其聲明順序的相反順序被調(diào)用;
- 如果有任何虛基類具有析構(gòu)函數(shù),而當(dāng)前討論的這個(gè)類是最尾真?zhèn)€類, 那末他們會(huì)以其原來的構(gòu)造順序的相反順序被調(diào)用;
生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對(duì)您的學(xué)習(xí)有所幫助,可以手機(jī)掃描二維碼進(jìn)行捐贈(zèng)