2012-04-09 154 views
20

我已经使用赋值运算符重载下面的代码C++超载:赋值运算符在

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; 
} 

其完美的工作,避免拷贝构造函数问题,但有这方面的任何未知的问题(我)?

+0

看看的[复制和交换成语(http://stackoverflow.com/questions/3279543/what-is-the-copy-and-swap -idiom) – Praetorian 2012-04-09 16:37:52

+1

@Praetorian复制和交换成语是好的,如果你知道一个项目可以赋值操作符期间抛出或者如果您正在使用软件时,您有没有发展,不知道是否会发生抛出。如果您正在使用自己的物品,并且您知道不会使用副本进行抛出,并且交换习语不是必需的。 – 2015-03-23 23:10:38

回答

10

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

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

+3

事实上的标准方式是*复制和交换*方法没有提到的。 – 2012-04-09 16:33:43

+1

@Als:复制和交换肯定是标准的,当你需要处理远程所有权。当处理一个简单的值时,我会称之为矫枉过正(尽管仍然可能比问题中的要好)。 – 2012-04-09 16:35:43

+0

@JerryCoffin:其实,我不主张复制和交换的单值调用,因为它是很难搞砸了复制和交换,一旦你学会了做正确的方式。 – 2012-04-09 16:37:25

4

二是相当标准。您通常更愿意返回赋值运算符的引用,以便按预期的方式解析像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) 
} 
+0

其实我想确定这个拷贝构造函数被调用的地方。我正在使用cout <<“我被称为”;在那里面。只有使用它才会导致问题。它不是复制值。 – kaushik 2012-04-09 16:41:03

+0

我指的是在第一个示例中按值返回副本。 – AJG85 2012-04-09 16:46:32

5

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

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

我认识许多老人和/或低质量书籍建议检查自我分配。然而,至少在我的经验中,如果没有它,你会变得更好(并且如果操作员依赖它来保证正确性,这几乎肯定不是例外)。

顺便说一句,我会注意的是定义一个圆,你一般需要一个中心和半径,当你复制或分配,要复制/分配两者。

0

这是正确的方式来使用运营商超载 现在你通过引用 避免价值复制你的对象。

-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 

} 
+3

如果您可以解释发布的代码段中的关键区域,则可以提供更多的帮助,而不仅仅是发布代码片段。 – RinoTom 2013-09-24 14:46:32