Runtime Semantics
C++的困难之一,就是不容易从代码看出来表达式的复杂,一个类似if(yy == xx.getValue())的简单式子,有可能经历操作符重载,转换运算符-》if( yy.operator == ( xx.getValue.operator Y() ));这些都由编译器暗中进行。
1、对象的构造和析构
一般而言,我们会把object尽可能放置在使用它的那个 程序区段附近,以节省不必要的产生对象和销毁操作。例如:{if ( cache )return 1;
Point XX;if ( xx == value )return 0;}如果我们在检查cache之前定义Point对象,就不够理想。
全局对象
Matrix indetity;
main()
{
Matrix m1 = indetity;
return 0;
}
C++保证,一定会在main函数中第一次用到indetity之前,把它构造出来,而在main结束之前把它销毁。
C++程序中所有的global object都被放置在程序的data segment中(其它的应该是在heap或stack中)。如果明确的给一个值,object将以该值为初值。否则object所配置的内存内容为0。
2、new和delete运算符
new运算符由两个步骤完成: int *pi = new int(5);
- 通过适当的new运算符函数实体,配置所需的内存:int *pi = __new( sizeof ( int ) );//调用函数库中的new运算符
- 给配置得来的对象设立初值:*pi = 5;//配置成功之后才执行,if(pi = __new( sizeof ( int ) )) *pi = 5;//成功了才初始化
delete运算符的情况类似。一般对于new运算符的实现操作都很直截了当,但有两个精巧之处值得斟酌(以下版本未考虑exception handling):
虽然 new T[0];是合法的。但语言要求每一次对new的调用都必须传回一个独一无二的指针,传统方法就是传回一个指针,指向一个默认为1-Byte的内存区块。extern void* operator new(size_t size) { if(size == 0) size = 1; void *last_alloc; while(!(last_alloc = malloc(size))) { if(_new_handler) { (*_new_handler)(); } else return 0; } return last_alloc; }
这个实现的另一个有趣之处就是,他允许使用者提供一个属于自己的_new_handler()函数。new运算符实际上总是以标准的C malloc()完成,虽然没有规定一定要这么做。相同的情况,delete运算符总是以标准的C free()完成。
Placement Operator newPoint2w *pt2 = new(arena)Point2w;其中arena指向内存中的一个区块,用以放置新产生出来的Point2w object。placement operator new的价值在于它所扩充的另一半是将Point2w constructor自动调用于arena所指的地址上。注意placement operator new并不支持多态,如Point2s *ptw = new (arena)Point3w;将会导致严重的破坏。