2013-03-18 66 views
2

假設構造函數,析構函數和賦值操作符編寫正確,爲什麼我不能執行拷貝構造是這樣的:在複製構造函數內調用動態分配的類'複製構造函數?

MyClass::MyClass(const MyClass &other) 
{ 
    this->value = new Value(*(other.value)); 
} 

大多數我看到的例子,這樣做:(因爲他們是處理通常陣列)

MyClass::MyClass(const MyClass &other) 
{ 
    Value *temp = new Value; 
    *temp = *(other.value); 
    this->value = temp; 
} 

但在第一個例子中,如果「新」拋出「其他」不會受到影響,如果值的拷貝構造函數拋出,也不會「新」釋放所分配的內存在宣傳例外之前?由於這是一個迷你智能指針本身,我特別避免使用std :: unique_ptr和其他智能指針。

+0

爲什麼'value'動態地擺在首位分配呢?你試圖以高成本賦予它價值語義,並且做錯了嗎? – sehe 2013-03-18 02:17:29

+0

值是指向另一個類的指針。也許「價值」這個名字是錯誤的詞 - 我應該使用更通用的「數據」或「其他類」。如果我是,「做錯了」,這就是爲什麼我問這個問題,因爲我不知道我是否正確地做對了。 – 2013-03-18 02:22:06

+0

那麼,它爲什麼是一個指針?如果複製'MyClass'意味着複製'value',那只是價值聚合。 – sehe 2013-03-18 02:23:27

回答

1

開始枚舉的問題太多了。我建議你學習規則三:

就像我說的,這裏的妥善解決將有可能讀

struct MyClass 
{ 
    MyClass(const MyClass &other) : value(other.value) {} 

    private: 
    OtherClass value; 
}; 

如果value是某種資源是必須住在堆上,那麼它將被宣佈爲

struct MyClass 
{ 
    // ... 
    private: 
     std::unique_ptr<OtherClass> value; 
}; 

這樣你不能(很容易)出現所有權語義和內存管理的問題。

+0

的陣營中紮實地進行。我在問一個關於我不明白的三條規則的部分問題。我在原來的問題中提到過。提供std :: unique_ptr雖然是一個很好的建議!但在這種情況下我特意避開它。 – 2013-03-18 02:30:13

2

如果Value的複製構造函數拋出不會在傳播異常之前釋放分配的內存嗎?

是。

沒有特別的理由不使用單線方法而不是三線分配版本。


既然你寫了以下內容不適用於智能指針,但在正常上課,你可能會換手動指針管理成一個RAII類型。它看起來像std::unique_ptr有你想要的語義和make_unique幫手使得它非常容易:

#include <memory> 

// probably will be added to the standard 
template<typename T, typename... Args> 
std::unique_ptr<T> make_unique(Args &&... args) { 
    return std::unique_ptr<T>(new T(std::forward<Args>(args)...)); 
} 

class Value {}; 

class MyClass { 
    std::unique_ptr<Value> value; 

public: 
    MyClass() : value{make_unique<Value>()} {} 

    MyClass(MyClass const &other) : value{make_unique<Value>(*other.value)} {} 

    MyClass &operator= (MyClass const &other) { 
     value = make_unique<Value>(*other.value); 
     return *this; 
    } 
    // you can also implement assignment from rvalue ref as an optimization 
}; 
+0

是的,這是因爲'其他'是常量,我說它不會受到影響 - 這部分不是一個問題,而是一個聲明。 =)謝謝你回答真正的問題!我已經有一個make_unique helper,並且在我的代碼中通常使用std :: unique_ptr和std :: shared_ptr,我應該提到我特意避免使用這個特定的類。哎呀。 – 2013-03-18 02:33:58