2013-11-04 22 views
1

我很難找出一種方法來返回一個對象(在函數中本地聲明),它具有連接到它的動態內存。問題是析構函數,它在對象超出作用域時運行並刪除動態內存,即當我返回它並想要使用已刪除內存中的數據時!我這樣做是爲了一個重載的加法運算符。用動態內存返回對象

我試着這樣做:

MyObj operator+(const MyObj& x, const MyObj& y) 
{ 
    MyObj z; 

    // code to add x and y and store in dynamic memory of z 

    return z; 
} 

我的析構函數很簡單:

MyObj::~MyObj() 
{ delete [] ptr; } 

任何建議,將不勝感激!

+3

讀了讀這:['C++:Three'的規則(HTTP:// EN .wikipedia.org/wiki/Rule_of_three_(C++ _ programming)),然後[這個問題和答案](http://stackoverflow.com/questions/4172722/what-is-the-rule-of-reeree)。 – WhozCraig

回答

2

您需要提供一個複製構造函數,將ptr的內容複製到新對象中。

如果MyObj沒有拷貝構造函數來複制ptr的內容,那麼您返回的對象將其ptr指向刪除的內存。不用說,如果您在這種情況下嘗試訪問ptr,那麼就會發生不好的事情。

通常,如果您必須爲您的類編寫析構函數,則還應該編寫一個複製構造函數和賦值運算符來處理任何動態內存或其他資源的複製。這是WhosCraig提到的三條法則。

如果您使用的是支持C++ 11現代的編譯器,你可能還需要在move semantics

3

沒關係。

不要擔心,在刪除之前,您的對象將被複制到另一個對象中或將被臨時使用。

但是...

嘗試寫一個定義良好的拷貝構造(如果你沒有的話)。 您應該服從rule of five

另一方面,您的代碼很有可能會進行RVO優化,以避免不必要的副本和一個額外的破壞。

此外,C++ 11提供了move semantics以避免不必要的副本。爲此,您應該寫移動構造函數移動分配

+0

你可能對RVO是正確的,但依靠這是危險的。 – Dima

+0

的確,我寫的說法是針對優化,而不是違反規則。 – deepmax

+0

等待,如果'MyObj'沒有複製'ptr'內容的複製構造函數就不行。 – Dima