赋值运算符在c ++中重载

kau*_*hik 32 c++ operator-overloading

我使用以下代码进行赋值运算符重载:

SimpleCircle SimpleCircle::operator=(const SimpleCircle & rhs)
{
     if(this == &rhs)
        return *this;
     itsRadius = rhs.getRadius();
     return *this;
}
Run Code Online (Sandbox Code Playgroud)

我的复制构造函数是这样的:

SimpleCircle::SimpleCircle(const SimpleCircle & rhs)
{
    itsRadius = rhs.getRadius();
}
Run Code Online (Sandbox Code Playgroud)

在上面的运算符重载代码中,复制构造函数被调用,因为正在创建一个新对象; 因此我使用了以下代码:

SimpleCircle & SimpleCircle::operator=(const SimpleCircle & rhs)
{
    if(this == &rhs)
       return *this;
    itsRadius = rhs.getRadius();
    return *this;
}
Run Code Online (Sandbox Code Playgroud)

它完美地工作并且避免了复制构造函数问题,但是对于这个问题(对我来说)是否存在任何未知问题?

jua*_*nza 17

赋值运算符的第二个版本没有问题.实际上,这是赋值运算符的标准方法.

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

  • 实际上标准的方法是*Copy&Swap*方法而不是提到的方法. (4认同)

AJG*_*G85 7

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

需要注意的一点是,如果您不需要深层复制,有时最好使用编译器生成的隐式复制构造函数和赋值运算符,而不是使用自己的复制构造函数和赋值运算符.真的很高兴你...

编辑:

这是一些基本的电话:

SimpleCircle x; // default constructor
SimpleCircle y(x); // copy constructor
x = y; // assignment operator
Run Code Online (Sandbox Code Playgroud)

现在说我们有你的赋值运算符的第一个版本:

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
}
Run Code Online (Sandbox Code Playgroud)

它调用复制构造函数并传递引用,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)
}
Run Code Online (Sandbox Code Playgroud)


Jer*_*fin 7

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

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

我意识到许多较旧和/或较低质量的书籍建议检查自我分配.然而,至少在我的经验中,如果没有它你会更好(并且如果操作员依赖于它的正确性,它几乎肯定不是安全的例外).

另外,我注意到要定义一个圆,你通常需要一个中心和一个半径,当你复制或分配时,你想复制/分配两者.