2013-10-15 89 views
0

我有一個類在構造函數的堆中聲明的private成員。然後,在析構函數中,它是delete ed。現在,我想添加一個方法來修改該變量。我希望能夠使用引用,但我不確定涉及的內存的具體情況,並且我想知道我正確地執行了該操作(該項目在內存部門中可能相當大)。參數:他們在哪裏申報?

class A 
{ 
private: std::string str; 
/* ... */ 
public: 
A() 
{ 
str = new std::string(""); 
} 
~A(){delete str;} 

// method to modify str. 
}; 

如果我通過引用傳遞,我應該採取什麼步驟,消除內存泄漏和減少內存使用情況?話雖如此,我並不想成爲所有優化的積極分子。

我應該如何爲堆上的成員編寫我的getter和setter?複製構造函數,別的東西?

+1

請注意,類std :: string已經執行它自己的內存管理,其中包括封裝複製構造函數,移動構造函數和賦值運算符。當你聚合一個已經擁有這個類的類時,你沒有必要再做一次。 –

+1

因此,如果在你的情況下,被聚合的類(私有成員)有它自己的內存管理(如std :: string那樣),而不要在堆上分配它。如果你關心在你的頭文件中需要很多依賴,這可能是使用堆的原因,那麼請使用pimpl_成語。 –

+0

在絕對需要它之前,不要使用指針和堆分配。 – Raja

回答

2

第一,private: std::string str;private: std::string* str;

您當前的內存管理模式是一個classic RIIA model.。首先,有幾個問題需要解決。

  • str對象將由A單獨擁有?
  • 是否想在類A的生命週期中使用str

如果您對上述內容回答「否」,則該模型不適合您的需要。

否則,你可以繼續實現這些成員函數,這裏我只是給出一些線索。

吸氣劑可以返回一個參考回來,

std::string const& getStr() { 
    return *str; 
} 

二傳手可能只是改變了值,

void setStr(std::string const& s){ 
    *str = s; 
} 

對於拷貝構造函數,你可以只調用從std::string拷貝構造函數,使深層副本,

A(A const& obj){ 
    str = new std::string(*obj.str); 
} 
+0

我認爲RAI​​I的維基頁是可怕的 - 一個更好的鏈接將是http://www.informit.com/articles/article.aspx?p=30642&seqNum=8 – Raja

+0

好鏈接,編輯。 –

+0

而不是聲明'str'作爲指針,它會更好地做,因爲另一個回答暗示:不使用'new'和'delete'。 –

4

你過於複雜化你的問題EM。代碼應該如下所示:

class A 
{ 
    private: std::string str; 

    public: 
     A() { str = ""; } 
     std::string GetStr() { return str; } 
     void SetStr(std::string value) { str = value; } 
}; 

構造函數使用空字符串初始化數據成員。你不需要任何破壞者。字符串類將爲你做所有的清理工作。您可以像上面的示例方法一樣使用數據字段。

請勿添加任何特殊的複製/移動方法。請仔細閱讀有關如何使用字符串類的手冊。

+1

「std :: string」的默認構造函數已經將它初始化爲空字符串。 –

+0

這是真的。我試圖接近原始代碼。 –

+1

Getter和setter應分別使用const&來返回參數。 :-) –