C++ c+中的赋值运算符重载+;
我使用了以下代码进行赋值运算符重载:C++ c+中的赋值运算符重载+;,c++,operator-overloading,C++,Operator Overloading,我使用了以下代码进行赋值运算符重载: SimpleCircle SimpleCircle::operator=(const SimpleCircle & rhs) { if(this == &rhs) return *this; itsRadius = rhs.getRadius(); return *this; } 我的副本构造函数是: SimpleCircle::SimpleCircle(const SimpleCircle &
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;
}
它工作正常,避免了复制构造函数的问题,但是(对我来说)有任何未知的问题吗?第二个版本的赋值运算符没有问题。事实上,这是赋值运算符的标准方式
编辑:请注意,我指的是赋值运算符的返回类型,而不是实现本身。正如评论中指出的那样,执行本身是另一个问题。请参阅。第二个是相当标准的。您通常更喜欢从赋值运算符返回引用,以便像
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)
}
在这种情况下,几乎可以肯定,您最好跳过对自我分配的检查——当您只分配一个看似简单类型(可能是双精度)的成员时,执行该分配通常比避免该分配更快,因此您最终会:
SimpleCircle & SimpleCircle::operator=(const SimpleCircle & rhs)
{
itsRadius = rhs.getRadius(); // or just `itsRadius = rhs.itsRadius;`
return *this;
}
我意识到许多旧的和/或低质量的书籍建议检查自我分配。然而,至少在我的经验中,很少有人认为没有它会更好(如果操作员依赖它来判断正确性,那么几乎可以肯定它不是异常安全的)
另一方面,我要指出的是,要定义一个圆,通常需要一个圆心和一个半径,当您复制或指定时,您需要同时复制/指定这两个圆。使用运算符重载是正确的方法
现在通过引用获取对象
避免值复制。这可能会有帮助:
// 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
}
C++中的代码> /操作符重载
//赋值运算符重载
#包括
使用名称空间std;
班级员工
{
私人:
int-idNum;
双薪;
公众:
雇员(){
idNum=0,工资=0.0;
}
无效设置值(int a、int b);
无效操作员=(员工和emp);
};
void Employee::setValues(int-idN,int-sal)
{
工资=sal;idNum=idN;
}
void Employee::operator=(Employee&emp)//赋值运算符重载函数
{
薪金=emp.薪金;
}
int main()
{
员工emp1;
emp1.设定值(10,33);
员工emp2;
emp2=emp1;//emp2正在使用赋值运算符调用对象
}
#包括
使用名称空间std;
班级员工
{
int-idnum;
双薪;
公众:
雇员(){}
雇员(内部a、内部b)
{
idnum=a;
薪金=b;
}
无效dis()
{
实际上,标准的方法是复制和交换方法,而不是前面提到的方法。@Als:Copy和Swap在需要处理远程所有权时当然是标准的。在处理单个简单值时,我将其称为overkill(尽管可能比问题中的更好)@JerryCoffin:事实上,我主张复制和交换单值调用,因为一旦你学会了正确的方法,复制和交换就很难搞砸了。@Als我指的是通过引用返回,而不是实现。我会澄清这一点。@Als:我通常主张的是,如果它只包含简单的值,那么默认的impleme安装将正常工作(并且应正常使用)。看看@Praetorian。如果您知道某个项目在赋值操作符期间可以抛出,或者您正在使用尚未开发的软件,但不知道是否会发生抛出,那么复制和交换习惯用法是很好的。如果您正在使用自己的项目,并且您知道不会发生抛出,那么使用复制和交换习惯用法是没有必要的lly我想确定调用此复制构造函数的位置。我使用的是coutI,在第一个示例中,它指的是按值返回副本。如果您能够解释发布的代码段中的关键区域,而不仅仅是像这样发布代码段,那么它会更有帮助。
#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();
}