2

次の演算子のオーバーロードテストを行いました。

#include <iostream>
#include <string>

using namespace std;

class TestClass
{
    string ClassName;

    public:

    TestClass(string Name)
    {
        ClassName = Name;
        cout << ClassName << " constructed." << endl;
    }

    ~TestClass()
    {
        cout << ClassName << " destructed." << endl;
    }

    void operator=(TestClass Other)
    {
        cout << ClassName << " in operator=" << endl;
        cout << "The address of the other class is " << &Other << "." << endl;
    }
};

int main()
{
    TestClass FirstInstance("FirstInstance");
    TestClass SecondInstance("SecondInstance");

    FirstInstance = SecondInstance;
    SecondInstance = FirstInstance;

    return 0;
}

代入演算子は期待どおりに動作し、他のインスタンスのアドレスを出力します。

では、実際に他のインスタンスから何かを割り当てるにはどうすればよいでしょうか。たとえば、次のようなものです。

void operator=(TestClass Other)
{
    ClassName = Other.ClassName;
}
4

5 に答える 5

5

代入演算子の従来の標準形は次のようになります。

TestClass& operator=(const TestClass& Other);

(割り当てのためにコピーコンストラクターも呼び出さないでください)そして、への参照を返します*this

単純な実装では、各データメンバーを個別に割り当てます。

TestClass& operator=(const TestClass& Other)
{
  ClassName = Other.ClassName;
  return *this;
}

(これはコンパイラーによって生成された代入演算子が行うこととまったく同じであることに注意してください。したがって、オーバーロードすることはまったく役に立ちません。ただし、これは演習用であると思います。)

より良いアプローチは、コピーアンドスワップイディオムを採用することです。(GManの答えがあまりにも圧倒的である場合は、のものを試してください。これは網羅的ではありません。:))C&Sは、割り当てを行うためにコピーコンストラクタとデストラクタを使用するため、質問で行ったように、オブジェクトをコピーごとに渡す必要があることに注意してください。

TestClass& operator=(TestClass Other)
于 2010-12-22T13:46:56.747 に答える
5

あなたが示したコードはそれをするでしょう。ただし、これが特に優れた実装であるとは誰も考えていません。

これは、代入演算子に期待されるものに準拠しています。

TestClass& operator=(TestClass other)
{
    using std::swap;
    swap(ClassName, other.ClassName);
    // repeat for other member variables;
    return *this;
}

ところで、あなたは「他のクラス」について話しますが、クラスは1つだけで、そのクラスのインスタンスは複数あります。

于 2010-12-22T13:49:02.047 に答える
3

ほとんどすべてが言った、いくつかのメモ:

  • 自己割り当てを確認します。if (&other != this) // assign
  • 演算子のオーバーロードに関する優れたガイドについては、こちらをご覧ください
于 2010-12-22T13:50:21.923 に答える
1

従来、代入演算子とコピーコンストラクターは、値によるコピーメカニズムではなく、const参照を渡して定義されていました。

class TestClass 
{
public:
    //... 
    TestClass& operator=(const TestClass& Other)
    {
        m_ClassName= Other.m_ClassName;
        return *this;
    }
private:
    std::string m_ClassName;
 }

編集:TestClass&を返さないコードを入れたので修正しました(@sbiの回答を参照)

于 2010-12-22T13:46:25.867 に答える
0

他のクラスからコンテンツをコピーする方法については正しいです。単純なオブジェクトは、を使用して割り当てることができますoperator=

ただし、TestClassポインタメンバーが含まれている場合は注意が必要です。を使用してポインタを割り当てるだけの場合operator=、両方のオブジェクトに同じメモリを指すポインタがあり、これは希望どおりではない可能性があります。代わりに、新しいメモリを割り当てて、ポイントされたデータをそのメモリにコピーして、両方のオブジェクトが独自のデータのコピーを持つようにする必要がある場合があります。また、コピーされたデータに新しいブロックを割り当てる前に、割り当てられたオブジェクトがすでに指しているメモリの割り当てを適切に解除する必要があることを忘れないでください。

ちなみに、あなたはおそらくあなたのoperator=ように宣言する必要があります:

TestClass & operator=(const TestClass & Other)
{
    ClassName = Other.ClassName;
    return *this;
}

これは、をオーバーロードするときに使用される一般的な規則operator=です。returnステートメントを使用すると、(などのa = b = c)割り当てを連鎖させることができ、参照によってパラメーターを渡すことで、関数呼び出しへの途中でのconstコピーを回避できます。Other

于 2010-12-22T13:46:23.107 に答える