base classes拥有destructor,它们将以声明的相反顺序而调用;
ü如果有任何virtual base classes拥有destructor,而前面讨论的这个class是most-derived class,那么它们会以原先构造顺序的相反顺序被调用。
2002-8-19
执行期语意学Runtime Semantics
6.1对象的构造和解构
1.一般而言,constructor和destructor的安插都如你所预期。但如果一个区段或函数中有一个以上的离开点,情况就会复杂一些,destructor会放在每一个离开点之前。通常,我们要求将object尽可能放在使用它的那个程序区附近,这样做可以节省不必要的对象产生和销毁操作。
2.C++程序中所有的global objects都被放置在程序的data segment中,如果不明确指定初值,object所配置的内存内容将为0(C并不自动设定初值)。如果global object有constructor和destructor的话,我们说它需要静态的初始化和内存释放操作。
2002-8-20
3.virtual base class的subobject在每个derived class中的位置可能会变动,不能在编译时期确定。以一个derived class的pointer或reference来存取virtual base class subobject,是一种nonconstant expression,必须在执行期方可评估求值。
4.使用静态初始化的object有一些缺点。其一,无法放入try区段,任何throw操作必将触发exception handling library的默认函数terminate();其二,程序员必须为控制“需要跨越模块做静态初始化”objects的依赖顺序而产生的复杂度付出代价。建议根本就不要使用那些需要静态初始化的global objects。
5.新的C++标准要求编译单位中的static local class objects必须在相应函数第一次被调用时才被构造,而且必须以相反的次序销毁。由于这些objects是在需要时才被构造,因此编译时期无法预期其集合和顺序。为支持新标准,可能要对被产生出来的static local class objects保持一个执行期链表。
2003-8-1
6.对于对象数组定义,晚近的编译器一般会提供两个函数,分别用于处理没有virtual base class的class,以及内带virtual base class的class,它们通常被称为vec_new、vec_vnew。前者类型通常为:
void* vec_new(//初始化程序员未提供初值的连续元素
void *array,//数组起始地址若为0,则动态分配
size_t elem_size,//每一个class object的大小
int elem_count,//数组中的元素数目
void (*constructor) (void *),// class的defaultconstructor指针
void (*destructor) (void *, char)// class的destructor指针,以0填入
);如果程序员提供带有默认参数值的default constructor,编译器要做特殊处理,以传入默认参数值!
对应销毁数组的两个函数分别为vec_delete、vec_vdelete。前者类型通常为:
void* vec_delete(
void *array,//数组起始地址
size_t elem_size,//每一个class object的大小
int elem_count,//数组中的元素数目
void (*destructor) (void *, char)// class的destructor指针
);
6.2 new和delete运算符
注意区分operator new和new operator!前者负责分配内存;后者先调用前者分配内存,然后调用constructor以实施初始化。