标签:
{ 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