2014-03-02 72 views
0

編寫類的拷貝構造函數會在析構函數中刪除對象時發生意外崩潰。請參見下面的代碼:編寫類的拷貝構造函數會在析構函數中刪除對象時發生意外崩潰

class ordinaryClass // Sample class is used in Foo class 
{ 
public: 
    ordinaryClass(){} 
}; 

class Foo 
{ 
public: 
    Foo():_ordinarayClass(0) 
    { 
     _ordinarayClass = new ordinaryClass(); 
    } 

    ~Foo() 
    { 
     delete _ordinarayClass; // the program crashes here when copy constructor is called. 
    } 

    Foo(const Foo &obj) // copy constructor 
    { 
     *_ordinarayClass = *obj._ordinarayClass; 
    } 

    Foo& operator=(const Foo& other) // copy assignment 
    { 
     *_ordinarayClass = *other._ordinarayClass; 
     return *this; 
    } 

    ordinaryClass *_ordinarayClass; 
}; 

在主,如果我寫這些代碼:

Foo container2; 
Foo container; 
container = container2; 

程序正常運行和正常退出。 但如果我把它寫在下面的方法:

Foo container2; 
Foo container = container2; 

程序崩潰而exites。我發現該程序在Foo類的析構函數中崩潰。 我在複製構造函數中犯了什麼錯誤? 非常感謝。

+2

'* _ordinarayClass = * obj._ordinarayClass;'調用未定義的行爲。問你自己什麼目標對象的'_ordinaryClass'指向你做這個任務。 – WhozCraig

+0

@WhozCraig:那麼我該如何寫這個類的複製構造函數和賦值?下面發佈了 – Mosi

+0

。正如我在答覆中所說的,首先考慮一下這個結構是否必須是動態的,因爲從我所看到的情況來看,它不應該是這樣,但是您比代碼更接近代碼。 – WhozCraig

回答

2

您需要的對象。不要只複製指針。我會保存「你應該使用智能指針進行這個演講」,因爲任何時間在這個網站上都會留下你短時間內眼瞼上的紋身(並且你應該使用智能指針= P)

class Foo 
{ 
public: 
    Foo() : _ordinaryClass(new ordinaryClass()) 
    { 
    } 

    virtual ~Foo() 
    { 
     delete _ordinaryClass; 
    } 

    Foo(const Foo &obj) : _ordinaryClass(new ordinaryClass(*obj._ordinaryClass)) 
    { 
    } 

    // copy/swap idiom for assignment. the value-parameter is 
    // intentional. think about what it does (hint: copy-ctor) 
    Foo& operator=(Foo other) 
    { 
     this->swap(other); 
     return *this; 
    } 

private: 
    ordinaryClass *_ordinaryClass; 

    // they get our cruft, we get theirs. 
    void swap(Foo& other) 
    { 
     std::swap(_ordinaryClass, other._ordinaryClass); 
    } 
}; 

我會認真重新該成員是否應該是擺在首位的動態,順便說一句。

+0

非常感謝,實際上類中的指針是一個指向抽象類的指針,所以我必須聲明它是動態的。 – Mosi

+0

@Mosi那麼你可能需要模板或提供工廠接口。對不起,我不知道那會提前,但是這個構造的一般問題會變得更加複雜,因爲這個類不知道'_ordinaryClass'指向的是什麼,如果它是一個抽象基礎。 – WhozCraig

+0

ordinaryClass類是一個抽象類,其他派生類在我的代碼中定義。在我的代碼中,我從一個孩子中派生出_ordinaryClass。 – Mosi