4

MSFT クラスから継承するため変更できないクラスがあります。派生クラスのコピー コンストラクターとコピー代入演算子が同じ動作をするようにしたいと考えています。私が抱えている問題は、コピーコンストラクターでは、初期化子リストで基本クラスのコンストラクターを自由に呼び出すことができますが、オペレーターでは、これはオプションではないということです。代入演算子でこの動作を適切に再現するにはどうすればよいですか? 演算子のオーバーロードの本体で基本クラスのコンストラクターを呼び出すだけで十分ですか?

追加の注意: 基本クラスは CObject から継承します。CObject には operator=() とコピー コンストラクターが非公開の未実装メソッドとして含まれているため、残念ながらそれらを呼び出すとコンパイル エラーが発生します。

以下に、簡略化されたコード シナリオを示します。

クラス宣言:

class Base    
{
protected:
    int baseInt;
public:
    Base(int);
}

class Derived : public Base
{
public:
    Derived(const Derived& other);
    Derived& operator=(const Derived& rhs);
private:
    int derivedInt;
}

派生クラス メンバー関数:

// Copy Constructor
Derived(const Derived& other) : Base(5)
{
    derivedInt = other.derivedInt;
}

// Copy Assignment Operator
Derived& operator=(const Derived& rhs)
{
    if (&rhs != this)
    {
        derivedInt = other.derivedInt;
        return *this;
    }
}

編集: 構文を更新し、CObject のメモを追加しました

4

2 に答える 2

7

一般的なケースでは、基本クラスのサブオブジェクトに対して operator= を明示的に呼び出すか、使用可能な場合は copy&swap イディオムを使用してこれを行います。

//explicit call to base operator=
Derived& operator=(const Derived& rhs)
{
  Base::operator=(rhs); //
  derivedInt = rhs.derivedInt;
  return *this;
}


//or copy&swap:
Derived& operator=(const Derived& rhs)
{
  Derived tmp(rhs); //copy
  tmp.swap(*this);
  return *this;
}

void swap(Derived& other)   
{
  Base::swap(other);
  std::swap(derivedInt,other.derivedInt);
}

更新:基本クラスはコピー割り当てを意図していないため、派生クラスもコピー割り当てしないでください。クラスにコピーできない部分が含まれていても、完全にコピーできる場合があります。このような場合、コピーできない部分は、クラス オブジェクトの状態に直接寄与しないものです (一意の ID など)。その後、これらのパーツは通常、割り当て中に変更されません。ただし、そのような場合、コピーできない部分は継承ではなく、集約によって含める必要があります。

簡単に言うと、継承とは「is-A」関係を意味します。あなたの基地はコピーできません。あなたの派生物はベースです。したがって、Derived もコピーできません。

于 2013-04-04T14:47:32.080 に答える
4

このような

Derived& operator=(const Derived& rhs)
{
    Base::operator=(rhs);
    derivedInt = rhs.derivedInt;
    return *this;
}
于 2013-04-04T14:45:20.303 に答える