37

代入演算子のオーバーロードに次のコードを使用しました。

SimpleCircle SimpleCircle::operator=(const SimpleCircle & rhs)
{
     if(this == &rhs)
        return *this;
     itsRadius = rhs.getRadius();
     return *this;
}

私のコピーコンストラクタはこれです:

SimpleCircle::SimpleCircle(const SimpleCircle & rhs)
{
    itsRadius = rhs.getRadius();
}

上記の演算子オーバーロードコードでは、新しいオブジェクトが作成されているときにコピーコンストラクターが呼び出されます。したがって、私は以下のコードを使用しました:

SimpleCircle & SimpleCircle::operator=(const SimpleCircle & rhs)
{
    if(this == &rhs)
       return *this;
    itsRadius = rhs.getRadius();
    return *this;
}

完全に機能し、コピーコンストラクターの問題は回避されますが、これに関して(私にとって)未知の問題はありますか?

4

6 に答える 6

20

代入演算子の2番目のバージョンには問題はありません。実際、これは代入演算子の標準的な方法です。

編集:実装自体ではなく、代入演算子の戻り型を参照していることに注意してください。コメントで指摘されているように、実装自体は別の問題です。ここを参照してください。

于 2012-04-09T16:30:24.940 に答える
8

2番目はかなり標準的です。代入演算子から参照を返すことを好むことがよくあります。そうすれば、のようなステートメントa = b = c;は期待どおりに解決されます。課題からコピーを返却したい場合は考えられません。

注意すべき点の1つは、ディープコピーが必要ない場合は、独自にロールするよりも、コンパイラーによって生成された暗黙的なコピーコンストラクターと代入演算子を使用するのが最善であると考えられる場合があることです。本当にあなた次第ですが...

編集:

ここにいくつかの基本的な呼び出しがあります:

SimpleCircle x; // default constructor
SimpleCircle y(x); // copy constructor
x = y; // assignment operator

ここで、代入演算子の最初のバージョンがあったとしましょう。

SimpleCircle SimpleCircle::operator=(const SimpleCircle & rhs)
{
     if(this == &rhs)
        return *this; // calls copy constructor SimpleCircle(*this)
     itsRadius = rhs.getRadius(); // copy member
     return *this; // calls copy constructor
}

コピーコンストラクターを呼び出し、this返されるコピーを作成するためにへの参照を渡します。2番目の例では、への参照を返すだけでコピーを回避します。this

SimpleCircle & SimpleCircle::operator=(const SimpleCircle & rhs)
{
    if(this == &rhs)
       return *this; // return reference to this (no copy)
    itsRadius = rhs.getRadius(); // copy member
    return *this; // return reference to this (no copy)
}
于 2012-04-09T16:30:51.060 に答える
7

このような状況では、自己割り当てのチェックをスキップする方がほぼ確実です。単純なタイプ(おそらくダブル)のように見えるメンバーを1つだけ割り当てる場合は、回避するよりも一般的にその割り当てを行う方が高速です。そのため、最終的には次のようになります。

SimpleCircle & SimpleCircle::operator=(const SimpleCircle & rhs)
{
    itsRadius = rhs.getRadius(); // or just `itsRadius = rhs.itsRadius;`
    return *this;
}

私は、多くの古い本や低品質の本が自己割り当てをチェックすることを勧めていることを理解しています。ただし、少なくとも私の経験では、それがない方が良いということは十分にまれです(そして、オペレーターが正確さのためにそれに依存している場合、それはほぼ確実に例外安全ではありません)。

余談ですが、円を定義するには、通常、中心と半径が必要であり、コピーまたは割り当てるときは、両方をコピー/割り当てる必要があります。

于 2012-04-09T16:34:32.023 に答える
1
#include<iostream>

using namespace std;

class employee
{
    int idnum;
    double salary;
    public:
        employee(){}

        employee(int a,int b)
        {
            idnum=a;
            salary=b;
        }

        void dis()
        {
            cout<<"1st emp:"<<endl<<"idnum="<<idnum<<endl<<"salary="<<salary<<endl<<endl;
        }

        void operator=(employee &emp)
        {
            idnum=emp.idnum;
            salary=emp.salary;
        }

        void show()
        {
            cout<<"2nd emp:"<<endl<<"idnum="<<idnum<<endl<<"salary="<<salary<<endl;
        }
};

main()
{
    int a;
    double b;

    cout<<"enter id num and salary"<<endl;
    cin>>a>>b;
    employee e1(a,b);
    e1.dis();
    employee e2;
    e2=e1;
    e2.show();  
}
于 2020-06-01T15:52:45.567 に答える
0

演算子のオーバーロードを使用する正しい方法です。これで、値のコピーを回避して参照によってオブジェクトを取得できます。

于 2012-04-09T16:34:43.453 に答える
-1

これは役立つかもしれません:

// Operator overloading in C++
//assignment operator overloading
#include<iostream>
using namespace std;

class Employee
{
private:
int idNum;
double salary;
public:
Employee ( ) {
    idNum = 0, salary = 0.0;
}

void setValues (int a, int b);
void operator= (Employee &emp );

};

void Employee::setValues ( int idN , int sal )
{

salary = sal; idNum = idN;

}

void Employee::operator = (Employee &emp)  // Assignment operator overloading function
{
salary = emp.salary;
}

int main ( )
{

Employee emp1;
emp1.setValues(10,33);
Employee emp2;
emp2 = emp1; // emp2 is calling object using assignment operator

}
于 2013-09-24T14:19:21.767 に答える