2010-08-12 119 views
6

在C++構造函數中,通過new分配內存的正確方法是哪種。在參數列表中第一種方式:在C++構造函數中分配內存的正確方法是什麼?

class Boda { 
    int *memory; 
    public: 
     Boda(int length) : memory(new int [length]) {} 
     ~Boda() { delete [] memory; } 
}; 

或在構造函數體:

class Boda { 
    int *memory; 
    public: 
     Boda(int length) { 
      memory = new int [length]; 
     } 
     ~Boda() { delete [] memory; } 
}; 

謝謝,博大Cydo。

+6

我知道這只是一個示例代碼,但是正如所寫的那樣,類存在嚴重的內存管理問題(默認拷貝文件將允許多次釋放內存)。使用RAII,使用智能指針或容器。有了適當的RAII,你可能會發現你根本不需要使用自己的刪除方法 – 2010-08-12 09:43:06

+8

@jk:借調,我更喜歡'std :: vector '。 – fredoverflow 2010-08-12 09:44:33

回答

3

我認爲最簡單的方法是使用boost scoped array,讓其他人經過良好測試的庫代碼爲您處理。

所以:

class Boda { 
    boost::scoped_array<int> memory; 
    public: 
     Boda(int length) : memory(new int [length]) {} 
     ~Boda() {} 
}; 

此外,作用域數組不能被複制 - 讓你避免在另一個答覆中提到討厭的拷貝構造函數釋放問題。

+0

其實,你應該使用'boost :: scoped_array'。 – 2010-08-12 11:39:31

+0

謝謝。剛剛發現它是一個數組alloc。教我正確地閱讀這個問題。 – 2010-08-12 11:40:21

+1

'delete'是一種代碼味道:它應該只出現在專用的資源管理類中......並且這些通常已經在可用的庫中正確編碼(例如STL/Boost)。 – 2010-08-12 14:18:36

-1

如果你想捕捉內存分配錯誤(你可能應該這樣做),那麼你必須在構造函數的主體中調用new。

+12

其實不然。 (在這兩種情況下,如果內存分配失敗,這個構造函數就無法做到這一點,所以不應該捕獲這個異常,並且可以使用函數try塊來獲取try-catch塊中的所有內容) – GManNickG 2010-08-12 09:43:10

1

我會說兩者在它們產生的效果上都是相等的,都是「正確的方式」。 我更喜歡初始值設定項列表,但爲了能夠在嘗試分配內存之前測試無效長度參數,我會選擇第二個變量。

+1

它們對於簡單類型是等同的,但通常它們不是。使用初始化列表將從參數構造對象;使用構造函數主體將默認構建對象,然後重新分配它。這可能效率較低,並且只有在對象是默認可構建和可分配的情況下才有效。 – 2010-08-12 17:16:47

2

您應該使用資源管理類來處理它。否則,除了不必要地複製現有的邏輯和維護複製/賦值操作符之外,您還會遇到一些嚴重的異常安全問題。

0

memory成員變量的指針,如果你在初始化列表分配它,它失敗了,你的類沒有初始化,你不需要稍後釋放它(由於所使用的C RAII設計模式++用於類初始化)。如果你在構造函數體內分配它的內存,會發生類似的行爲。

但是,如果你想處理的東西,然後分配它的內存在構造函數的正文。檢查某個東西或嘗試/捕獲它或打印一些有用的消息,但至少必須拋出另一個異常,因爲您的類初始化已被破壞。

我認爲memory在構造函數體內的分配比另一個更具可讀性。

相關問題