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

赋值运算符的第二个版本没有问题。事实上,这是赋值运算符的标准方式。

编辑:请注意,我指的是赋值运算符的返回类型,而不是实现本身。正如评论中所指出的,实施本身是另一个问题。见这里

于 2012-04-09T16:30:24.940 回答
8

第二个很标准。您通常更喜欢从赋值运算符返回引用,以便像a = b = c;预期的那样解析语句。我想不出任何我想从作业中返回副本的情况。

需要注意的一件事是,如果您不需要深度复制,有时认为最好使用编译器生成的隐式复制构造函数和赋值运算符,而不是自己滚动。真的取决于你...

编辑:

以下是一些基本调用:

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构造要返回的副本。现在在第二个例子中,我们通过返回一个引用来避免复制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

在这种情况下,您几乎肯定最好跳过检查自分配 - 当您只分配一个似乎是简单类型(可能是双精度)的成员时,执行该分配通常比避免分配更快它,所以你最终会得到:

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 回答