2012-01-06 54 views
4

據我所知,有3 general ways修改的新的行爲,並刪除C++:重載,覆蓋和替換新/刪除有什麼限制?

  • 更換默認new/delete和新的[] /刪除[]
  • 重寫超載放置版本(覆蓋傳遞給它的內存位置,在創建傳遞其他類型或數量參數的版本時重載)
  • 重載類特定版本。

對new/delete的行爲進行這些修改的限制是什麼?

特別是有新的和刪除可以用於簽名的限制?

這是有道理的,如果任何更換版本必須具有相同的簽名(否則他們不會更換或會破壞其他代碼,如STL爲例),但它是允許有全局佈局或類特定版本返回智能指針或一些自定義句柄,例如?

+1

相關和可能是有用的:[我應該如何編寫ISO C++標準符合自定義新的和刪除操作符?](http://stackoverflow.com/questions/7194127/how-should-i-write-iso-c-標準符合性的自定義新的和刪除的運營商) – 2012-01-06 06:30:36

回答

3

首先,不要混淆新/刪除表達operator new()功能

表達式是執行構造和破壞的語言構造。運算符是執行內存(分配)分配的普通函數。

只有默認運算符(operator new(size_t)operator delete(void *)可以用默認使用newdelete表達式。所有其他形式的簡易稱爲「位置」的形式,併爲那些你只能使用new,但你必須手動銷燬對象通過調用析構函數,佈局表單是相當有限且專門的需求,到目前爲止,最有用的佈局形式是全局佈局 - 新的,::new (addr) T,但其行爲甚至不能被改變(這可能是爲什麼它是唯一受歡迎的) 。

全部new運營商必須返回void *。這些分配函數遠低於低等級比你想象的要好,所以基本上你會「知道什麼時候你需要惹他們」。

重複一遍:C++分離了對象構造和內存分配的概念。你所能做的就是爲後者提供替代實現。

+0

很好理解,分配和構建是分開的任務。因此,新關鍵字的定期使用將執行分配和構建,而新位置表單僅執行施工?所以我想所有的佈局表單都需要有一個void *來知道在哪裏構造對象?或者讓編譯器知道構建對象的位置?如果新的佈局版本被告知在哪裏構建,他們是否仍然需要返回void *? – Bingo 2012-01-06 11:58:56

+0

只有全局默認的placement-new(':: operator new(size_t,void *)')保證爲空操作。其他職位表格以及班級成員職能可以做任何他們喜歡的事情。新運算符的每種形式都必須返回一個'void *',它成爲對象的'this'指針。 – 2012-01-06 12:53:30

+0

對,我想我現在變得更好了。因此,只有默認的全球位置新保證不分配,但任何自定義的..他們是自定義的,可能會或可能不分配。但是它們都返回void *並且編譯器接受這個void *,使它成爲* this並調用構造函數來在該內存位置構造對象。這是正確的嗎?我得出的結論是,沒有重載的new操作符顯式調用構造函數,它在操作符new執行「分配」之後全部由編譯器完成。 – Bingo 2012-01-06 13:10:33

0

當你在一個類中重載新的和刪除的時候,你正在有效地修改爲該類分配和釋放內存的方式,並要求它爲你提供這個控件。

當某個類想要使用某種池來分配其實例時,可能會執行此操作,以進行優化或用於跟蹤目的。

與幾乎所有的操作符重載一樣,限制條件是您可能會傳遞的參數列表以及預期遵守的行爲。

+0

是的,「限制......是你可能傳遞的參數列表,以及它所期望遵守的行爲。」標準行爲在針對問題發佈的鏈接中概述,但是我必須傳遞哪些參數列表?如果它非常像其他運營商,我可以做任何事情。它可以是什麼樣的返回類型? – Bingo 2012-01-06 11:38:42