深度探索C++對象模型筆記(六)

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);

  1. 通過適當的new運算符函數實體,配置所需的內存:int *pi = __new( sizeof ( int ) );//調用函數庫中的new運算符
  2. 給配置得來的對象設立初值:*pi = 5;//配置成功之後才執行,if(pi = __new( sizeof ( int ) )) *pi = 5;//成功了才初始化
delete運算符的情況類似。

一般對於new運算符的實現操作都很直截了當,但有兩個精巧之處值得斟酌(以下版本未考慮exception handling):

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 T[0];是合法的。但語言要求每一次對new的調用都必須傳回一個獨一無二的指針,傳統方法就是傳回一個指針,指向一個默認爲1-Byte的內存區塊。

這個實現的另一個有趣之處就是,他允許使用者提供一個屬於自己的_new_handler()函數。new運算符實際上總是以標準的C malloc()完成,雖然沒有規定一定要這麼做。相同的情況,delete運算符總是以標準的C free()完成。


Placement Operator new

Point2w *pt2 = new(arena)Point2w;其中arena指向內存中的一個區塊,用以放置新產生出來的Point2w object。placement operator new的價值在於它所擴充的另一半是將Point2w constructor自動調用於arena所指的地址上。注意placement operator new並不支持多態,如Point2s *ptw = new (arena)Point3w;將會導致嚴重的破壞。

3、臨時性對象


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章