简体   繁体   English

为什么在调用重载的赋值运算符时调用了拷贝构造函数?

[英]why copy constructor is called at the time of calling overloaded assignment operator?

i am trying to understand the use of constructors and assignment operators. 我试图了解构造函数和赋值运算符的用法。 I am trying with this below program. 我正在尝试下面的程序。

#include <iostream>
using namespace std;

class myclass {
    int x;
public:
    myclass (int p) {
        cout << "calling constructor" << endl;
        x = p;
    }
    myclass () {
        cout << "calling constructor with no arguments" << endl;
        x = 0;
    }
    myclass (myclass &t) {
        cout << "calling copy constructor" << endl;
        x = t.x;
    }

    myclass operator=(myclass &t) {
        cout << "calling assignment operator" << endl;
        x = t.x;
        return *this;
    }

    void show () {
        cout << "val = " << x << endl;
    }
};


int main() {
    myclass a1;
    a1.show();
    myclass a2 = a1;
    a2.show();
    myclass a3(a2);
    a3.show();
    myclass a4(200);
    a2 = a4;
    a2.show();
    return 0;
}

Output: 输出:

calling constructor with no arguments // call 1
val = 0
calling copy constructor // call 2
val = 0
calling copy constructor // call 3
val = 0
calling constructor // call 4
calling assignment operator // call 5
calling copy constructor // call 6 i am not able to understand this print line
val = 200

call 1, is done from myclass a1; 调用1是从myclass a1完成的;

call 2, is done from myclass a2 = a1; 调用2是从myclass a2 = a1完成的;

call 3, is done from myclass a3(a2); 调用3,是从myclass a3(a2)完成的;

call 4, is done from myclass a4(200); 调用4是从myclass a4(200)完成的;

call 5, is done from a2 = a4; 调用5是从a2 = a4完成的;

but i am not able to get where call 6 is coming from, it is called from the instruction: 但是我无法获得呼叫6的来源,它是从指令中调用的:

a2 = a4;

But, how it will give call to copy constructor? 但是,它将如何调用复制构造函数?

any help/pointer wil be a great help. 任何帮助/指针将是一个很大的帮助。 I am diving into cpp from c, hence please bear with me. 我正在从c潜入cpp,因此请多多包涵。

(You copy constructor and assignment operators are slightly malformed: they ought to take a const reference as the argument, and the assignment operator ought to return a reference not a value). (您复制的构造函数和赋值运算符的格式略有错误:它们应将const引用作为参数,而赋值运算符应返回引用而不是值)。

With myclass a2 = a1; myclass a2 = a1; , a2 doesn't yet exist. a2尚不存在。 So the copy constructor is called to create a2 using a1 . 因此,调用复制构造函数使用a1创建a2

But with a2 = a4 , a2 already exists, so the assignment operator is used to assign a2 to a4 . 但是对于a2 = a4a2已经存在,因此使用赋值运算符 a2 分配a4

So the rule is essentially: If an object doesn't exist then it needs to be constructed. 因此,规则本质上是:如果对象不存在,则需要对其进行构造。 Your observed output can be explained by applying this rule. 您可以通过应用此规则来解释观察到的输出。

 myclass operator=(myclass &t) {
    cout << "calling assignment operator" << endl;
    x = t.x;
    return *this;
}

The above function returns by value. 上面的函数按值返回。 Returning by value is one of the cases when copy constructor is called. 按值返回是调用复制构造函数的情况之一。 Also AFAIK, this is not always true(returning by value calling copy constructor) as some compilers implement return value optimization. 同样是AFAIK,这并不总是正确的(通过调用复制构造函数的值返回),因为某些编译器实现了返回值优化。

change it to 更改为

myclass& operator=(myclass &t)

then: 然后:

calling constructor with no arguments
val = 0
calling copy constructor
val = 0
calling copy constructor
val = 0
calling constructor
calling assignment operator
val = 200

If you return by value, copy ctor will be called. 如果按值返回,则将调用复制ctor。 Return by reference to avoid calling copy ctor. 通过引用返回以避免调用副本ctor。

Your assignment operator returns by value , so there's another copy made when it returns. 您的赋值运算符按value返回,因此返回时还有另一个副本。

That's where the sixth call is coming from. 那是第六个电话的来历。

Typically, an assignment operator returns a reference instead, so that when you return *this , you really do return *this : 通常,赋值运算符返回一个引用 ,因此,当您return *this ,实际上确实会返回*this

myclass& operator=(myclass &t) {
//     ^

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

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