一、对象的构造和解构
一般而言,constructor和destructor的安插都如下:
//C++伪码
{
Point point;
// point.Point::Point() //一般会被安插在这里
...
// point.Point::~Point() //一般会被安插在这里
}
如果一个作用域或函数中有一个以上的离开点,情况会稍微混乱一些。Destructor必须被放在每一个离开点之前,例如:
{
Point point;
// constructor 在这里
switch( int (point.x()) ) {
case -1:
//...
// destructor在这里
return;
case 0:
//...
//destructor在这里
return;
case 1:
//...
//destructor在这里
return;
default:
//...
//destructor在这里
return;
}
//destructor在这里
}
在这个例子中,point的destructor必须在switch指令四个出口的return操作前被生成出来。另外也很有可能在这个作用域的结束符号之前被生成出来。因此,一般而言,我们会把object尽可能放置在使用它的那个程序区段附近,这样做可以节省不必须的对象产生操作和摧毁操作。
全局对象
C++程序中所有的global objects都被放置在程序的data segment中。如果明确指定给它一个值,object将以该值为初值,否则object所配置到的内容为0(这和C略有不同,C并不自动设定初值)。对于全局的class object,其在编译时期可以被放置于data segment中并且内容为0,但constructor一直要到程序运行时才会执行。
对于每个全局对象,编译器会为其产生一个相应的初始化函数和内存释放函数,这些函数在编译时期就通过一定的方法链接起来,并插在main函数的开始处和结束处。

局部静态对象
对于局部静态对象,可以通过创建一个临时性的标记对象,用来判断在函数调用的时候局部静态对象是否已经被初始化,而不用在程序启动的时候将所有局部静态对象都构造出来。
二、对象数组
对于像下面的数组定义:
Point knots[10];
Point有一个default constructor,因此这个constructor必须轮流施行于knots每一个元素之上。在cfront中,使用一个命名为vec_new()的函数,产生出以class objects构造而成的数组。比较晚近的编译器,包括Borland、Microsoft和Sun,则是提供了两个函数,一个用来处理“没有virtual base class”的class,另一个用来处理“内带virtual base class”的class。后一个函数通常称为vec_vnew()。函数类型通常如下(当然在各平台上可能会有些许差异存在):
void* vec_new(
void *array, //数组起始地址
size_t elem_size, //每一个class object的大小
int elem_count, //数组中的元素数目
void (*constructor)( void* ),
void (*destructor)( void*, char)
}
其中constructor和destructor参数是这个class的default constructor和default destructor的函数指针,虽然constructor和destructor在程序代码是没法获取到的,但是在这里有编译器的支持,因此完全可以获取到constructor和destructor的函数指针。下面是编译器可能针对上面定义的10个Point元素所做的vec_new()调用操作:
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)
}
如果在程序员代码中提供了一个或多个明显初始给一个由class objects组成的数组,像下面这样:
Point knots[10] = {
Point(),
Point(1.0, 1,0, 0.5),
-1.0
};
那么,对于那些明显获得初值的元素,vec_new()不再有必要。对于那些尚未被初始化的元素,vec_new()的施行方式就可能被转换为:
Point knots[0]; //明确地初始化前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);