? 一般而言,constructor和destructor的安插都如預(yù)期那樣:
成都創(chuàng)新互聯(lián)是一家專(zhuān)注于網(wǎng)站制作、成都網(wǎng)站制作與策劃設(shè)計(jì),金口河網(wǎng)站建設(shè)哪家好?成都創(chuàng)新互聯(lián)做網(wǎng)站,專(zhuān)注于網(wǎng)站建設(shè)10年,網(wǎng)設(shè)計(jì)領(lǐng)域的專(zhuān)業(yè)建站公司;建站業(yè)務(wù)涵蓋:金口河等地區(qū)。金口河做網(wǎng)站價(jià)格咨詢(xún):13518219792
{
Point point;
//point.Point::Point() 安插于此
...
//point.Point::~Point() 安插于此
}
? 但有些情況desctructor需要放在每一個(gè)離開(kāi)點(diǎn)(此時(shí)object還存活)前,例如swith,goto:
{
Point point;
//point.Point::Point() 安插于此
swith ( int(point.x() ) )
{
case -1 :
...
//point.Point::~Point() 安插于此
return;
case 0 :
...
//point.Point::~Point() 安插于此
return;
case 1 :
...
//point.Point::~Point() 安插于此
return;
default :
...
//point.Point::~Point() 安插于此
return;
}
//point.Point::~Point() 安插于此
}
? 解決c++ global object constructor和destructor的方法步驟:
為每一個(gè)需要初始化的文件產(chǎn)生__sti(),內(nèi)含必要的constructor或inline expansions
在每個(gè)需要內(nèi)存釋放的文件中產(chǎn)生__std(),內(nèi)含必要的destructor或inline expansions
提供一組rumtime library munch函數(shù):一個(gè)_main()用以調(diào)用可執(zhí)行文件中的所有__sti(),和一個(gè)exit()用以調(diào)用可執(zhí)行文件中的所有__std()
//matrix_c也就是matrix.c文件名,identity為static object
__sti__matrix_c__identity()
{
identity.Matrix::Matrix();
}
int main()
{
_main();
...
_exit();
}
? local static class object保證:
? 要支持以上行為,需要導(dǎo)入臨時(shí)性對(duì)象以保護(hù)local static class object,第一次處理此object時(shí),臨時(shí)對(duì)象被賦值為false,此時(shí)constructor被調(diào)用,臨時(shí)對(duì)象被改為true。取地址保證單一的構(gòu)造和析構(gòu):
//如下程序片段
const Matrix& identity()
{
static Matrix mat_identity;
//...
return mat_identity;
}
//編譯器策略之一
static struct Matrix* __0__F3 = 0;
struct Matrix* identity__Fv()
{
static struct Matrix__lmat__identity;
//若臨時(shí)性對(duì)象已被建立,什么也別做
//否則:調(diào)用constructor:__ct__6MatrixFv
//設(shè)定保護(hù)對(duì)象,使它指向目標(biāo)對(duì)象
__0__F3 ? 0 : (__ct__6MatrixFv( &__1mat_identity), (__0__F3 = ( &1mat_identity) ) );
//...
}
//destructor在與文件有關(guān)聯(lián)的靜態(tài)內(nèi)存釋放函數(shù)中有條件地被調(diào)用
char __std__stat_0_c_j()
{
__0__F3 ? __dt__6MatrixFv( __0__F3, 2 ) : 0;
//...
}
? 現(xiàn)有如下片段:
Point knots[10];
? 對(duì)于以上數(shù)組,若Point并沒(méi)有定義constructor和destructor,只需配置內(nèi)存存儲(chǔ)元素即可。但若定義了,一般來(lái)說(shuō)會(huì)經(jīng)由一個(gè)或多個(gè)runtime library函數(shù)完成:
void* vec_new(
void* array, //數(shù)組起始地址.若不是具名數(shù)組則為0
size_t elem_size, //每個(gè)class object的大小
int elem_count, //數(shù)組中元素個(gè)數(shù)
void(*constructor)( void* ), //class的default constructor的函數(shù)指針
void ( *destructor )( void*, char ) //class的default destructor的函數(shù)指針
);
void* vec_delete
{
void* array, //數(shù)組起始地址
size_t elem_size, //每個(gè)class object的大小
int elem_count, //數(shù)組中元素個(gè)數(shù)
void ( *destructor )( void*, char )
}
//函數(shù)調(diào)用如下:
vec_new( &knots, sizeof(Point), 10, &Point::Point, 0 );
我們不可以取constructor的地址,只有編譯器可以
vec_new的主要功能是將default constructor施行于class object組成的數(shù)組的每個(gè)元素
? 若提供一個(gè)或多個(gè)明顯初值給class object組成的數(shù)組,編譯器會(huì)顯示地初始化前面提供了顯式初值的元素,再用vec_new初始化后面未提供的
? new運(yùn)算符看起來(lái)是單一運(yùn)算,但其實(shí)由兩個(gè)步驟完成:
int* pi = new int(5);
//new
int* pi;
if( pi = __new( sizeof( int ) ) ) *pi = 5; //內(nèi)存分配成功才初始化
//delete與new相似
if( pi != 0 ) __delete( pi ); //pi并不會(huì)清除為0
? 若用constructor配置class object:
//new
Point3d* origin = new Point3d;
Point3d* origin;
if( origin = __new( sizeof(Point3d) ) ) origin = Point3d::Point3d(origin);
//若是exception handling
if( origin = __new( sizeof(Point3d)))
{
try
{
origin = Point3d::Point3d(origin);
}
catch(...)
{
__delete(origin);
throw;
}
}
//delete
delete origin;
if( origin != 0 )
{
Point3d::~Point3d(origin);
__delete(origin);
}
? library對(duì)new運(yùn)算符的實(shí)現(xiàn)。要求每次new傳回獨(dú)一無(wú)二的指針:
extern void* operator new(size_t size)
{
if( size == 0 ) size == 1;
void* last_alloc;
while( !(last_alloc == malloc(size)))
{
//使用者自己的函數(shù)
if( _new_handler ) ( *_new_handler )();
else return 0;
}
return last_alloc;
}
? 現(xiàn)有如下片段:
int * p_array = new int[5];
int* p_array = (int*)__new( 5 * sizeof(int));
struct A{ float f1; };
A* p_a = new A[5];
? 以上兩種方式都不會(huì)調(diào)用vec_new,因?yàn)関ec_new的主要功能是將default constructor施行于class object組成的數(shù)組的每個(gè)元素,第二個(gè)例子沒(méi)有定義constructor或destructor。但第一個(gè)實(shí)例會(huì)調(diào)用new operator
? 以下片段會(huì)調(diào)用vec_new:
Point3d* p_array = new Point3d[10];
//轉(zhuǎn)化
Point3d* p_array;
p_array = vec_new( 0, sizeof(Point3d), 10, &Point3d::Point3d, &Point3d::~Point3d );
? 以下兩種delete如今都支持:
int array_size = 10;
Point3d* p_array = new Point3d[array_size];
delete [array_size]p_array;
delete []p_array;
? 現(xiàn)有如下片段:
class Point
{
public:
Point();
virtual ~Point();
//...
};
class Point3d: public Point
{
public:
Point3d();
virtual ~Point3d();
//...
};
? 此時(shí),配置內(nèi)含10個(gè)Point3d objects的數(shù)組,Point和Point3d的constructor各被調(diào)用10次。但調(diào)用delete,大有不同:
Point* ptr = new Point3d[10];
//只有~Point()調(diào)用,且只傳遞了Point class object的大小
delete [] ptr;
for( int ix = 0; ix < elem_count; ++ix )
{
Point3d* p = &( (Point3d*) ptr )[ix];
delete p;
}
? 調(diào)用方式:
Point2w* ptw = new ( arena ) Point2w; //arena指向內(nèi)存的一個(gè)區(qū)塊,放置新產(chǎn)生的Point2w object
void* operator new( size_t, void* p )
{
return p;
}
? 但是以上只是placement operator new操作的一半,擴(kuò)充的另一半將class object constuctor自動(dòng)實(shí)施于arena所指地址:
Point2w* ptw = ( Point2w* ) arena;
if( ptw != 0 ) ptw->Point2w::Point2w();
? 對(duì)于"Point2w* ptw = new ( arena ) Point2w;",我們無(wú)法知道arena所指的這塊區(qū)域是否需要先析構(gòu)
//錯(cuò)的
Point2w* p2w = new (arena) Point3w;
當(dāng)前題目:c++對(duì)象模型 執(zhí)行期語(yǔ)義
轉(zhuǎn)載注明:http://chinadenli.net/article14/dsoiege.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供搜索引擎優(yōu)化、品牌網(wǎng)站制作、、云服務(wù)器、做網(wǎng)站、網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容