标签:
{
Point point;
// point.Point::Point() 一般而言会被插入在这里
...
// point.Point:;~Point() 一般而言会被插入在这里
} 如果一个区段(以{}括起来的区域)或函数中有一个以上的离开点,情况会稍微混乱一点.Destructor必须被放在每一个离开点(当时object还存活)之前,例如:{
Point point;
// constructor 在这里行动
switch (int(point.x())) {
case -1:
// mumble
// destructor 在这里行动
return;
case 1:
// mumble
// destructor 在这里行动
return;
default:
// mumble
// destructor 在这里行动
return;
}
// destructor在这里行动
}
在这个例子中,point的destructor必须在 switch 指令四个出口的 return 操作前被生成出来,另外也很可能在这个区段的结束符号(右大括号)之前被生成出来——即使程序的分析的结果发现绝对不会进行到那里.{
if (cache2)
// 检查cache;如果吻合就传回1
return 1;
Point xx;
// xx的constructor 在这里行动
while (cvs.iter(xx))
if (xx == value)
goto found;
// xx的destructor 在这里行动
return 0;
found:
// cache item
// xx的destructor 在这里行动
return 1;
} Destructor调用操作必须放在最后两个 return 指令之前,但是却不必被放在最初的 return 之前,因为那时object尚未被定义出来.Matrix identity;
main() {
// identity 必须在此处被初始化
Matrix m1 = identity;
...
return 0;
}
C++保证,一定会在main()函数中第一次用到identity之前,把identity构造出来,而在main()函数结束之前把identity销毁.像identity这样的所谓的 global object 如果有constructor或destructor的话,它需要静态的初始化操作和内存释放操作.int v1 = 1024; int v2;v1和v2都被配置于程序的data segment,v1值为1024,v2值为0(这和C略有不同,C并不自动设定初值).在C语言中一个global object只能够被一个常量表达式(可在编译时期求值的那种)设定初值.当然,constructor并不是常量表达式.虽然 class object在编译时期可以被放置于data segment中并且内容为0,但constructor一直要到程序激活(startup)时才会实施.必须对一个"放置于program data segment中的object的初始化表达式"做评估,这正是为什么一个object需要静态初始化的原因.
__sti__matrix_C__identity() {
identity.Matrix::Matrix(); // 这就是 static initialization
} 其中matrix_c是文件名编码,_identity表示文件中所定义的第一个 static object.在__sti之后附加上这两个名称,可以为可执行文件提供一个独一无二的识别符号.const Matrix &identity() {
static Matrix mat_identity;
// ...
return mat_identity;
} Local static class object保证了什么样的语意?// 被产生出来的临时对象,作为戒护之用
static struct Matrix *__0__F3 = 0;
// C++的reference在C中以pointer来代替
// identity()的名称会被mangled
struct Matrix *identity_Fv() {
static struct Matrix __lmat_identity;
// 如果临时性的保护对象已经被设立,就什么也不做,否则
// a.调用constructor:__ct__6MatrixFv
// b.设定保护对象,使它指向目标对象
__0__F3 ? 0 (__ct__6MatrixFv(&__lmat_identity), (__0__F3 = (&__lmat__identity)));
}
最后,destructor必须在"与 text program file有关联的静态内存释放函数(static deallocation function)"中被有条件地调用.Point knots[10];需要完成什么呢?如果Point既没有定义一个constructor也没有定义一个destructor,那么工作不会比建立一个"内建(build-in)类型所组成的数组"更多,也就是说,只需配置足够的内存以储存10个连续的Point元素.
void *vec_new() {
void *array, // 数组起始地址
size_t elem_size, // 每一个class object的大小
int elem_count; // 数组中的元素数目
void (*constructor)(void *),
void (*destruction)(void *, char)
} 其中constructor和destructor参数是这个 class 的default construct和default destructor的函数指针.Point knots[10]; vec_new(&knots, sizeof(Point), 10, &Point::Point, 0);如果Point也定义了一个destructor,当knots的生命结束时,该destructor也必须施行于那10个Point元素上.这是一个经由一个类似的vec_delete()的runtime library函数完成的,其函数类型如下:
void *vec_delete{
void *array, // 数组起始地址
size_t elem_size, // 每一个class object的大小
int elem_count, // 数组中的元素数目
void (*destructor)(void *, char)
} 有些编译器会另外增加一些参数,用以传递其他数值,以便能有条件地导引vec_delete()的逻辑,在vec_delete()中,destructor被施行于elem_count个元素上.Point knots[10] = {
Point,
Point(1.0, 1.0, 0.5),
-1.0
}; 对于那些明显获得初值的元素,vec_new不再有必要.对于那些尚未被初始化的元素,vec_new()的施行方式就像面对"由class elements组成的数组,而该数组没有explicit initialization list"一样,因此上一个定义很可能被转换为:Point knots[10]; // 明确地初始化前3个元素 Point::Point(&knots[0]); Point::Point(&knots[1], 1.0, 1.0, 0.5); Point::Point(&knots[2], -1.0, 0.0, 0.0); // 以vec_new初始化后7个元素 vec_new(&knots+3, sizeof(Point), 7, &Point::Point, 0);
版权声明:本文为博主原创文章,未经博主允许不得转载。
标签:
原文地址:http://blog.csdn.net/yiranant/article/details/47688137