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;將會導致嚴重的破壞。