为什么赋值运算符重载会创建对象的副本?

Why does assignment operator overloading create a copy of an object?

提问人:Vishesh Arya 提问时间:5/22/2020 最后编辑:Remy LebeauVishesh Arya 更新时间:5/22/2020 访问量:324

问:

在下面给定的代码中,我在所有类构造函数、析构函数和重载赋值运算符中编写了语句。cout

#include <iostream>
using namespace std;

class person {
    string name;
    int age ;
    int id ;
    static int num;
public :
    person (string name , int age) : name(name) , age(age) {
        id = num++;
        cout << "creating person : " << id << "(" << name <<")"<< endl;
    }
    person (const person &other) : name(other.name) , age(other.age) {
            id = num++;
            cout << "CREATING PERSON  : " << id << "(" << name <<")" << " from : " << other.id << endl;
    }
    ~person () {
        cout << "killing person : " << id << "(" << name <<")" << endl;
    }
    const person operator= (const person &other) {
        name = other.name ;
        age = other.age;
        //id = num++;
        cout << "copying in : " << id << "(" << name <<")" << " from : " << other.id << endl;
        return *this;
    }
    void print () {
        cout << "name : " << name << ", age : " << age << ", id : " << id << endl;
    }

int person::num = 1;

int main() {
    person per1 ("p1" , 20);
    person per2 ("p2" , 30);
    person per3 ("p3" , 40);
    cout << "see the strange object creation here: " << endl << endl;
    per3 = per2 = per1;
    return 0;
}

给定代码的输出结果如下:

creating person : 1(p1)
creating person : 2(p2)
creating person : 3(p3)
see the strange object creation here:
copying in : 2(p1) from : 1
*CREATING PERSON  : 4(p1) from : 2*
copying in : 3(p1) from : 4
*CREATING PERSON  : 5(p1) from : 3*
killing person : 5(p1)
killing person : 4(p1)
killing person : 3(p1)
killing person : 2(p1)
killing person : 1(p1)

我的问题是,是什么导致使用复制构造函数创建两个对象(4 和 5)?分配中使用的对象已存在。有没有办法在不创建虚拟对象的情况下重载赋值运算符?这种方法似乎不是很优化。

C++ operator-重载 copy-constructor

评论


答:

8赞 user10957435 5/22/2020 #1

那是因为你看起来像这样:operator=()

const person operator= (const person &other)

这是按值返回的。 在这种情况下真的没有意义。const

您实际要做的是通过常量引用返回:

const person& operator= (const person &other)

这将使一切变得不同。&

评论

1赞 Vishesh Arya 5/22/2020
哇!它确实让一切变得不同。我不再创建不需要的对象,非常感谢您的见解。您能否详细说明我在以前的代码中创建副本的确切位置?是在返回“this”期间还是在将“this”分配给另一个对象期间?
0赞 5/22/2020
别客气。如果需要,您可以对此答案投赞成票,或者如果该答案已解决您的问题,请单击它旁边的复选标记将此答案标记为已接受。
0赞 user4581301 5/22/2020
@VisheshArya 我认为你对无法投票的看法是对的,但如果你现在不能选择这个作为答案,你应该很快就能做到。您应该用复选标记标记显示如何解决问题的答案,以向未来的提问者表明该问题已成功回答。
1赞 user4581301 5/22/2020
@VisheshArya 一些推荐阅读的内容应该可以回答你的一些问题:按引用传递与按值传递有什么区别?
3赞 Remy Lebeau 5/22/2020
@VisheshArya “你能详细说明我在以前的代码中创建副本的确切位置吗?”——当按值返回时,会为被“ed”的对象创建一个副本。将返回值从 to (不应返回 from ) 可避免进行复制。*thisreturnpersonperson&constoperator=