2017-11-30 17 views
0

ディープコピーを実行するために代入演算子のオーバーロードを使用しようとしていますが、正しい方法を見つけることができません。私はクラスコンピュータを持っていて、そのオブジェクトをクラスラップトップのものにコピーするためにそれを使用する必要があります。C++で代入演算子のオーバーロードを実装する方法は?

+0

正確に何をしたいのかのコードサンプルは高く評価されます。 –

答えて

1

それは次のようになります。

非ポインタメンバ変数については
#include <algorithm> 

class SomeClass {}; 
class AnotherClass {}; 

class Computer 
{ 
public: 
    Computer() : 
    m_someclass(new SomeClass()), 
    m_double(0.0) 
    { 
    } 

    virtual ~Computer() 
    { 
    delete m_someclass; 
    } 

    Computer(const Computer& other) : 
    m_someclass(new SomeClass(*other.m_someclass)), 
    m_double(other.m_double) 
    { 
    } 

    Computer& operator=(const Computer& other) 
    { 
    if (this != &other) 
    { 
     Computer tmp(other); 
     swap(tmp); 
    } 
    return *this; 
    } 

    void swap(Computer& other) noexcept // or throw() for before c++11 
    { 
    std::swap(m_someclass, other.m_someclass); 
    std::swap(m_double, other.m_double); 
    } 

private: 
    SomeClass* m_someclass; 
    double m_double; 
}; 

class Laptop : public Computer 
{ 
public: 
    Laptop() : 
    m_anotherclass(new AnotherClass()), 
    m_int(0) 
    { 
    } 

    virtual ~Laptop() 
    { 
    delete m_anotherclass; 
    } 

    Laptop(const Laptop& other) : 
    Computer(other), 
    m_anotherclass(new AnotherClass(*other.m_anotherclass)), 
    m_int(other.m_int) 
    { 
    } 

    // Create a Laptop object from a Computer object 
    explicit Laptop(const Computer& other) : 
    Computer(other), 
    m_anotherclass(new AnotherClass()), 
    m_int(0) 
    { 
    } 

    Laptop& operator=(const Laptop& other) 
    { 
    if (this != &other) 
    { 
     Laptop tmp(other); 
     swap(tmp); 
    } 
    return *this; 
    } 

    // Assign a laptop object from a computer object. 
    Laptop& operator=(const Computer& other) 
    { 
    if (this != &other) 
    { 
     Laptop tmp(other); 
     swap(tmp); 
    } 
    return *this; 
    } 

    void swap(Laptop& other) noexcept // or throw() for before c++11 
    { 
    Computer::swap(other); 
    std::swap(m_anotherclass, other.m_anotherclass); 
    std::swap(m_int, other.m_int); 
    } 

private: 
    AnotherClass* m_anotherclass; 
    int m_int; 
}; 

int main() 
{ 
    Computer computer; 

    // Construct a new Laptop object by copying data from a Computer object 
    Laptop laptop1(computer); 

    // Assign Computer data in Laptop to that of a Computer object 
    Laptop laptop2; 
    laptop2 = computer; 
} 

は、あなただけの作業で、標準コピーを実行します=。オブジェクトが所有するポインタメンバ変数の場合は、new演算子を使用して、他のオブジェクトが持つポインタで構築します。

+0

通常、新しいリソースを設定する前に古いリソースを解放する必要があります。したがって、 'if(m_someclass && m_someclass!= other.m_someclass)delete m_someclass;をチェックして、m_someclassを上書きする必要があります。 other.m_someclass!= nullptrの場合にのみコピーコンストラクタも呼び出します。 –

+0

ああ、非常に良い点。ただし、nullポインタを削除しても安全だから、削除する前に 'if(m_someclass)'をチェックする必要はありません。また、各オブジェクトがそのm_someclassを「所有している」場合、2つの異なるオブジェクトが同じm_someclassを持つとは思わない。しかし、私はとにかくそこに小切手を入れました。例外安全のために一時的なポインタに 'new SomeClass'を使用しました。新しいスローの場合、m_someclassは同じままです。どう考えているか教えてください。 –

+0

オーナーシップが明白な場合は、右と右をもう一度押します。まだ例外的に安全ではありません。一般的には、コードを分割して最初から分割し、スローしない2番目の部分にメンバー変数を設定する必要があります。これで、m_double siは上書きされますが、m_someclassは上書きされないという状況になります。それを下に移動するか、temp varを使用することができます。 "3のルール"に従うようにクラスを修正することもできます –

関連する問題