/*
*C++ 語言學習
* —— placement 語法
* 內容來自網上及摘自 C++ Strategies and Tactics
*/
Placement New
關鍵字new能夠接受參數:
p = new(arg1, arg2, arg3) D;
這些參數會被隱含地傳給new操做函數:
p = operator new(sizeof(D), arg1, arg2, arg3);
注意,第一個參數仍然是要生成對象的字節數,其它參數老是跟在它後面。
標準運行庫定義了一個new操做的特別重載版本,它接受一個額外參數:
void * operator new(std::size_t, void *);
這種形式的new操做被以下的語句隱含調用:
p = new(addr) D;
這裏,addr是某些數據區的地址,而且類型兼容於void *。addr傳給這個特別的new操做,這個特別的new操做和其它new操做同樣返回將被構造的內存的地址,但不須要在自由內存區中再申請內存,它直接將addr返回:
void *operator new(std::size_t, void *addr)
{
return addr;
}
這個返回值而後被傳給D::D做構造函數的this指針。
就這樣,表達式:
p = new(addr) D;
在addr所指的內存上構造了一個D對象,並將p賦爲addr的值。這個方法讓你有效地指定新生成對象的位置,因此被叫做「placement new」。
這個new的額外參數形式最初被設計爲控制對象的位置的,可是C++標準委員會認識到這樣的傳參體系能夠被用於任意用途而不只是控制對象的位置。不幸的是,術語「placement」已經被根據最初目的而制訂,並適用於全部new操做的額外參數的形式,即便它們根本不試圖控制對象的位置。
因此,下面每一個表達式都是placement new的一個例子:
new(addr) D; // calls operator new(std::size_t, void *)
new(addr, 3) D; // calls operator new(std::size_t, void *, int)
new(3) D; // calls operator new(std::size_t, int)
即便只有第一個形式是通常被用做控制對象位置的。
placement Delete
如今,只要認爲 placement delete 是有用處的就好了。我確定會講述理由的,可能就在接下來的兩篇內。
Placement new操做和placement delete操做必須成對出現。
通常來講,每個
void *operator new(std::size_t, p1, p2, p3, ..., pN);
都對應一個
void operator delete(void *, p1, p2, p3, ..., pN);
根據這條原則,標準運行庫定義了
void operator delete(void *, void *);
以對應我剛講的placement new操做。
數組New和數組Delete
基於對稱,標準運行庫也申明瞭placement new[]操做和placement delete[]操做:
void *operator new[](std::size_t, void *);
void operator delete[](void *, void *);
如你所料:placement new[]操做返回傳入的地址,而placement delete[]操做的行爲和我沒有細述的placement delete操做行爲幾乎同樣。 數組
下面摘自《C++ Strategies and Tactics》 函數
經過在緊接着 new 關鍵字後使用括號列表,用戶能夠向 operator new 傳遞參數: