標籤:style blog http color 使用 art ar div
基本概念:
1. 操作符重載:C++支援對某個操作符賦予不同的語義
2. new操作符:申請記憶體,調用建構函式
關於c++ new操作符的重載
你知道c++ 的new 操作符和operator new 的區別嗎?也許你還會問,他們有區別嗎?
當你寫下面這樣的代碼時,
string *pa = new string("memory managerment");
你使用的是new 操作符,這個操作符和sizeof 一樣,是c++ 語言層級支援的。你不能改變它的語義,它做的事情總是不變的:分配足夠的記憶體以容納對象,然後調用建構函式初始化上一步所分配的記憶體。New 操作符總是做這兩件事情,你不能改變它的行為。
你所能改變的只是第一步的行為,如何為對象分配RAW 記憶體。operator new 函數用來為對象分配原始記憶體。New操作符的第一步調用的就是operator new 。你可以重載這個函數。它的原型如下:
Void* operator new(size_t size);
函數的傳回值是void*, 因為這個函數返回的是指標。這個指標指向原生的,為初始化的記憶體。其語義就像malloc 。實際上它內部調用的就是malloc 。參數size 指定待分配的記憶體大小。你可以在重載的時候加上額外的參數,但是第一個參數類型必須是size_t.
絕大多數情況下,你不需要調用operator new, 萬一你需要調用它,調用的格式是這樣的:
Void* rawmemory = operator new(sizeof(string));
函數operator new 將返回一個指標,指向一塊足夠容納一個string 對象的記憶體。
就像malloc 一樣,operator new 的唯一的職責就是分配記憶體,它對建構函式一無所知。把operator new 返回的未初始化的指標構造成一個對象是new 操作符的工作。當你的編譯器遇到以下的代碼時:
string *pa = new string("memory managerment");
它產生的虛擬碼類以如下:
void* memory = operator new(sizeof(string));call string::string("memory managerment") on memory ;string* Pa = static_cast<string*>(memory);
第二布包含了建構函式的調用。這是你的編譯器調用的。那麼你不緊會問,程式員可以手動調用建構函式嗎?答案是否定的。但是編譯器同時給你提供了另外一個折中,是你可以達到這個目的。
需要說明的是,在一個已存在的對象上調用建構函式是沒有任何意義的。因為建構函式用來初始化對象。但是有時候有一些記憶體已經被分配但是尚未初始化,你需要在這些記憶體中構造一個對象。你可以使用operator new 函數的一個特殊版本。一個術語叫 placement new 的函數來做這件事情。
回到前面那個字串的例子,我們可以這樣使用placement new :
Void* memory = operator new(sizeof(string));String* pa = new (memory) string("memory managerment");
以上兩句就相當於new 操作符所做的事情了。
這就是operator new 和placement new 的全部秘密。一般的來說,你不需要重載和顯式調用這兩個函數。
原文地址:http://blog.csdn.net/bichenggui/article/details/4823978#comments