繁体   English   中英

为什么复制赋值运算符的参数应该是引用?

[英]Why should the parameter to a copy assignment operator should be a reference?

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

这里真的有两个问题:

1)您定义的复制赋值运算符不会被调用 这条线

Student dst=src;

不会调用复制赋值运算符! 它调用复制构造函数 ,它由编译器隐式定义。 但是,如果你写了

Student dst;
dst = src;

然后将调用operator=

2)是的,目的是避免复制。 当你调用一个函数,包括operator= ,它取值Student ,必须复制Student对象参数(通过对复制构造函数的隐式调用)。 另一方面,如果该函数采用引用,则不进行复制。

因为否则它将通过值传递,这是一个副本,因此您需要调用复制构造函数来调用复制构造函数...

这个

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

在C ++ 03中,除了将s复制到目标对象之外,通过const引用传递避免为本地s创建一个可能非常昂贵的新副本,它永远不会被修改。

在C ++ 11中,现在我们已经移动了语义:赋值可能导致资源转移到新对象或资源复制。 可以利用pass-by-copy操作来生成用于目标对象的复制数据,从而充分利用开销。 如果使用move传递,则没有副本。 C ++ 11中的最佳实践是让单个函数同时作为复制和移动赋值运算符:

Student& Student::operator=(Student s)
{
    name = std::move( s.name );
    num = s.num;
    return *this;
}

简单。 看看这段代码。

Student a, b;
a = b;

它等于

a.operator=(b);

b按值传递。 所以调用了复制构造函数

a.operator=(Student(b)); // please notice that it is just psudo code..

因此,有两个复制! 一个是复制构造函数 ,另一个是复制赋值运算符 这是不必要的。


而且, 复制构造函数的参数也必须是引用。 否则, 无限递归发生,因为按值调用需要复制和复制需要按值调用和...

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM