简体   繁体   English

当我从赋值运算符返回值时,首先调用复制构造函数的机制和基础是什么?

[英]When I return by value from an assignment operator, firstly what is the mechanism and basis of calling the copy constructor?

Consider this piece of code and its output: 考虑这段代码及其输出:

class test {    
    int a, b;

    public:
        test (int a, int b) : a(a), b(b) { cout << "Const" << endl;}

        test (const test & t) {
            cout << "Copy constructor" << endl;
            cout << "Being copied to = " << this << " from " <<  &t << endl;
            if (&t == this) {
                cout << "returning" << endl;
               return;
            }
            this->a = t.a;
            this->b = 6;//t.b;
        }

        test operator=(const test & in) {
        cout << "Assignment operator" << endl;
        this->a = in.a;
        this->b = in.b;
        cout << "Being written to = " << this << " from  "<< &in << endl;
        return *this;
    }

    test get () {
        test l = test (3, 3);
        cout << "Local return " << &l << endl;
        return l;
    }

    void display () {
        cout << a << " " << b << endl;
    }
};

int main () {
    int i = 5, &ref = i;
    test t(1,1), u(2,2);

    u = t.get();
    cout << "u address" << &u <<endl;
    //cout << "u ka = " << &u << endl;
    u.display();   
}

Output: 输出:

Const
Const
Const
Local return 0x7fff680e5ab0
Assignment operator
Being written to = 0x7fff680e5a90 from  0x7fff680e5ab0
Copy constructor
Being copied to = 0x7fff680e5a80 from 0x7fff680e5a90
u address0x7fff680e5a90
3 3

I know the way to return from an assignment is by reference, but I was trying to understand how this works since I am a beginner to C++. 我知道从作业返回的方式是参考,但我试图理解这是如何工作的,因为我是C ++的初学者。 What is the address 0x7fff680e5a80 ? 地址0x7fff680e5a80是什么? Where is this coming from ? 这是从哪里来的? Which object is calling the copy constructor here ? 哪个对象在这里调用复制构造函数? I would expect u (address 0x7fff680e5a90) to call it. 我希望你(地址0x7fff680e5a90)可以调用它。

Lets follow your code (I modified your constructor to dump the constructed this). 让我们按照你的代码(我修改你的构造函数来转储构造它)。

First you isntantiate t and u. 首先,你是t和你。

Const at 0x7fffffffdeb0
Const at 0x7fffffffdea0

Then you call t.get, which initializes l. 然后你调用t.get,初始化l。

Const at 0x7fffffffdec0

You then return l. 然后你回来了。

Local return 0x7fffffffdec0

The copy constructor that would normally happen at this point is elided. 通常在此时发生的复制构造函数被省略。

Assignment operator from l to u
Being written to = 0x7fffffffdea0 from  0x7fffffffdec0

Then you are returning the assignment by value (you should return it by reference), so you copy from u to an output value that isn't stored (0x7fffffffde90 from u) 然后你按值返回赋值(你应该通过引用返回它),所以你从u复制到一个未存储的输出值(来自你的0x7fffffffde90)

Copy constructor
Being copied to = 0x7fffffffde90 from 0x7fffffffdea0

And then you print u. 然后你打印你。

u address0x7fffffffdea0

Inside T. 里面T.

To get rid of the confusing (and unessisary copy) you should return by reference when you do any assignment operator: 为了摆脱混乱(和unessisary副本),当你做任何赋值运算符时,你应该通过引用返回:

test& operator=(const test & in);

Your assignment operator is incorrect: 您的赋值运算符不正确:

    test operator=(const test & in) {

You should return by reference: 你应该通过引用返回:

    test &operator=(const test & in) {

The object at 0x7fff680e5a80 is a prvalue temporary object of type test that is returned from your (incorrect) assignment operator and immediately discarded: 0x7fff680e5a80处的对象是一个类型为test的prvalue临时对象,它从(不正确的)赋值运算符返回并立即丢弃:

test operator=(const test & in) {
    cout << "Assignment operator" << endl;
    this->a = in.a;
    this->b = in.b;
    cout << "Being written to = " << this << " from  "<< &in << endl;
    return *this;
}   //     ^-- copy constructor is called here

You can check this by taking an rvalue reference to the return value of the assignment operator: 您可以通过对赋值运算符的返回值进行右值引用来检查:

auto &&temp = (u = t.get());
std::cout << "Address of temp: " << &temp << std::endl;  // prints 0x7fffffffde90

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

相关问题 在赋值运算符中调用复制构造函数 - calling copy constructor in assignment operator 在复制构造函数中调用赋值运算符 - Calling assignment operator in copy constructor 按值返回是否调用复制构造函数或复制赋值运算符? - Does a return by value call the copy constructor or the copy assignment operator? 当我对具有复制构造函数但没有赋值运算符的对象进行赋值时会发生什么? - What happens when I make a assignment to object which has copy constructor but no assignment operator? 从赋值运算符调用构造函数 - Calling the constructor from the assignment operator 复制构造函数或赋值运算符? 我想念什么? - Copy constructor or assignment operator? What am I missing? 按值的赋值运算符不使用显式副本构造函数进行编译 - assignment operator by value not compiling with explicit copy constructor 复制构造函数和赋值运算符的类似值的实现 - Value -like implementation of copy constructor and assignment operator 赋值运算符不调用参数化构造函数,而代码中存在复制构造函数 - Assignment operator is not calling parameterized constructor while copy constructor present in code 当有复制构造函数时,是否总是需要赋值运算符? - Is assignment operator always necessary when there is a copy constructor?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM