“opperator =应该采用(当然,const最好)参考src obj的参数”,我在很多书中看到这一点,但我尝试使用非ref,它也有效!所以,是什么使用ref的目的是为了避免从param复制?我的测试代码是,
#include <iostream>
#include <string>
using namespace std;
class Student{
public:
Student& operator=(Student);
string name;
int num;
};
Student& Student::operator=(Student s)
{
name=s.name;
num=s.num;
return *this;
}
int main(){
Student src;
src.name="haha";
src.num=11;
cout<<src.name<<" "<<src.num<<endl;
Student dst=src;
cout<<src.name<<" "<<src.num<<endl;
}
答案 0 :(得分:1)
这里确实存在两个问题:
1)您已定义的副本分配运算符未被调用。这条线
Student dst=src;
不会调用复制赋值运算符!它调用复制构造函数,它由编译器隐式定义。但是,如果你写了
Student dst;
dst = src;
然后会调用operator=
。
2)是的,目的是避免复制。当您调用函数(包括operator=
,其值为Student
时,必须复制Student
对象参数(通过对复制构造函数的隐式调用)。另一方面,如果该函数采用引用,则不进行复制。
答案 1 :(得分:1)
因为否则它将通过值传递,这是一个副本,因此您需要调用复制构造函数来调用复制构造函数...
答案 2 :(得分:0)
此
Student& Student::operator=(Student s)
{
name=s.name;
num=s.num;
return *this;
}
应该是
Student& Student::operator=(const Student &s)
{
if (this == &s) return *this;
name=s.name;
num=s.num;
return *this;
}
使用引用来避免浪费CPU
答案 3 :(得分:0)
在C ++ 03中,通过const
引用可以避免为本地s
创建一个可能非常昂贵的新副本,除了将s
复制到目标对象。
在C ++ 11中,现在我们已经移动了语义:赋值可能导致资源转移到新对象或资源复制。可以利用pass-by-copy操作来生成用于目标对象的复制数据,从而充分利用开销。如果您使用move
传递,则没有副本。 C ++ 11中的最佳实践是让单个函数同时作为复制和移动赋值运算符:
Student& Student::operator=(Student s)
{
name = std::move( s.name );
num = s.num;
return *this;
}
答案 4 :(得分:0)
简单。看看这段代码。
Student a, b;
a = b;
等于
a.operator=(b);
和b
按值传递。所以调用复制构造函数。
a.operator=(Student(b)); // please notice that it is just psudo code..
因此,有两次复制!一个是复制构造函数,另一个是复制赋值运算符。没必要。
此外,复制构造函数的参数也必须是引用。否则,无限递归会发生,因为按值调用需要复制和复制需要按值调用和...