024 定位 new 表達式

定位 new 表達式

盡管 operator new 函數和 operator delete 函數一般用于 new 表達式,然而它們畢竟是標準庫函的兩個普通函數,因此普通的代碼也可以直接調用它們。

在 C++ 早期版本中,allocator 還不是標準庫的一部分。應用程序如果想把內存分配與初始化分離開來的話,需要調用 operator new 和 operator delete。這兩個函數的行為與 allocatorallocate 成員和 deallocate 成員非常類似,它們負責分配或釋放內存空間,但是不會構造或銷毀對象。

allocator 不同的是,對于 operator new 分配的內存空間來說我們無法使用 construct 函數構造對象。相反,我們應該使用 new定位 new(placement new) 形式構造對象。如我們所知,new 的這種形式為分配函數提供了額外的信息。我們可以使用定位 new 傳遞一個地址,此時定位 new 的形式如下所示:

new (place_address) type;
new (place_address) type (initializers);
new (place_address) type [size];
new (place_address) type [size] { braced initializer list }

釋義:

  • place_address 必須是一個指針
  • initializers 中提供一個(可能為空的)以逗號分隔的初始值列表,該初始值列表將用于構造新分配的對象。

當僅通過一個地址值調用時,定位 new 使用 operator new(size_t, void*) 分配內存。這是 一個我們無法自定義的 operator new 版本。該函數不分配任何內存,只是簡單地返回指針實參;然后由 new 表達式負責在指定的地址初始化對象以完成整個工作。事實上,定位 new 允許我們在一個特定的、預先分配好的內存地址上構造函數。

注意: 當只傳入一個指針類型的實參時,定位 new 表達式構造對象但是不分配內存。

定位 new 類似于 allocator 類的 construct 成員,但在它們之間也有一個重要的區(qū)別。我們傳遞給 construct 的指針必須指向同一個 allocator 對象分配的空間,但是傳給定位 new 的指針無須指向 operator new 分配的內存。實際上,傳給定位 new 表達式的指針甚至不需要指向動態(tài)內存。

顯式的析構函數調用

類似于定位 newallocate 類一樣,對析構函數的顯式調用也與使用 destroy 一樣。我們既可以通過對象調用析構函數,也可以通過對象的指針或引用調用析構函數,這與調用其他成員函數沒有什么區(qū)別:

std::string *sp = new std::string("a value");
sp->~string(); // 調用析構函數銷毀對象,但是 sp 所指的內存沒有釋放

和調用 destroy 類似,調用析構函數可以銷毀對象但是不會釋放內存空間。因此我們可以反復利用這個內存空間。例如:

std::string *sp = new std::string("a value");
sp->~string();
sp = new std::string("new value"); // 重新使用 sp 所指的內存空間進行對象的構造

注意: 調用析構函數可以銷毀對象,但是不會釋放內存。

本文非原創(chuàng),內容摘錄自《C++ Primer 中文版(第 5 版)》,為了有更多的知識能夠傳播,請多多支持正版。

?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

友情鏈接更多精彩內容