2011-07-17 35 views
0

我想重寫一個類型的構造函數涉及調用new(也就是說,構造函數需要動態分配其他東西),因此它的析構函數涉及調用delete 。冥冥之中,我想能夠使用這樣的:在C++中爲動態分配類型重載+運算符

T c = a + b; 

我的問題是,我顯然需要創建+函數內部類型T的對象。如果我在+函數實現內部的堆棧中分配一個T的臨時實例以返回副本,那麼此實例的析構函數將在+調用退出並且(或者我相信)分配給c之前被調用。所以這不是一個選項。我的其他選項似乎是使用new並在返回時取消引用新返回的指針。然而,這種方法的問題似乎是指針將無法訪問,並且無法在其上調用delete

所以我的問題是......它不可能是超載運營商的類型涉及動態分配是罕見的。人們通常如何處理這種情況?

+0

我不明白這個問題。如果你的類型'T'在它的構造函數中有'new'並且在它的析構函數中有'delete',對於某個成員,那麼這有什麼問題? –

+0

我想寫T c = a + b;問題是+函數需要返回一個T類型的對象。我應該在哪裏創建這個對象?在+函數中的堆棧中不起作用 - 它在超出範圍時會調用它,當它從+函數返回時,就在必要的賦值之前!我應該使用新的關鍵字,然後在返回時解除引用?但是,我永遠無法恢復由新返回的指針,我永遠不會刪除它,導致內存泄漏。 – Gravity

+0

嗯......複製構造函數在通過複製返回值時會自動調用嗎?像這樣的東西將是必要的,以使我想要做的工作。這是C++的設計者爲解決這類問題而實現的嗎(因此在其他文章中提到了複製構造函數?) – Gravity

回答

3

你確定T服從The Rule of 3,不用擔心。

+0

感謝您的鏈接。你的鏈接讓我意識到我的代碼可能容易出現奇怪的內存錯誤,因爲我沒有製作一個拷貝構造函數。但是,我直接說明的擔憂呢?爲什麼遵循三條規則,將我從上述情況中拯救出來? – Gravity

+0

@Gravity:因爲'return'複製了返回值(除非NRVO發生,請參閱@ tg的答案,但是銷燬會延遲)。 –

+0

對,我現在明白了。我不知道返回調用了一個拷貝構造函數,而不是做一個按位(C風格)的拷貝。 – Gravity

0

std::stringstd::vector在某種程度上能夠做到這一點,你的班級也是如此。我不建議你學習他們的源代碼,這是相當嚇人的。另一張海報說,3的規則是你的朋友。我可以補充說,你應該而不是在你的函數中調用new。在堆棧上分配並按值返回。 C++將會做必要的魔術。

3

如果您在operator+創建堆棧臨時對象,然後退出,這取決於編譯器和您的運營商實現:

  1. 對象將通過拷貝構造函數傳遞到另一個臨時對象,將被傳遞再次通過複製構造函數到c
  2. 該對象將通過複製構造函數傳遞給c
  3. 臨時對象實際上是c,並且不會有複製構造函數調用。 (見http://en.wikipedia.org/wiki/Return_value_optimization

正如前面提到的,如果你遵循的3治國,並提供正確的執行拷貝構造函數和賦值運算符將不會有任何情況下的任何問題,所以你不必擔心關於實際執行情況(除非你對性能感到瘋狂)。這就是OOP。

+0

+1。我的問題是,我只是不明白如何通過副本工作。 – Gravity