1

考虑这段代码及其输出:

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();   
}

输出:

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

我知道从作业中返回的方法是通过引用,但我试图了解这是如何工作的,因为我是 C++ 的初学者。地址 0x7fff680e5a80 是什么?这是从哪里来的?哪个对象在这里调用复制构造函数?我希望你(地址 0x7fff680e5a90)调用它。

4

2 回答 2

2

让我们按照您的代码进行操作(我修改了您的构造函数以转储构造的 this)。

首先,您不区分 t 和 u。

Const at 0x7fffffffdeb0
Const at 0x7fffffffdea0

然后调用 t.get,它初始化 l。

Const at 0x7fffffffdec0

然后你返回 l。

Local return 0x7fffffffdec0

此时通常会发生的复制构造函数被省略了。

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

然后你按值返回赋值(你应该通过引用返回它),所以你从 u 复制到一个未存储的输出值(0x7fffffffde90 from u)

Copy constructor
Being copied to = 0x7fffffffde90 from 0x7fffffffdea0

然后你打印你。

u address0x7fffffffdea0

T内。

为了摆脱令人困惑的(和不必要的副本),您应该在执行任何赋值运算符时通过引用返回:

test& operator=(const test & in);
于 2014-03-21T16:35:06.980 回答
1

您的赋值运算符不正确:

    test operator=(const test & in) {

您应该通过引用返回:

    test &operator=(const test & in) {

at的对象是从您的(不正确的)赋值运算符返回并立即丢弃0x7fff680e5a80的类型的纯右值临时对象:test

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

您可以通过对赋值运算符的返回值进行右值引用来检查这一点:

auto &&temp = (u = t.get());
std::cout << "Address of temp: " << &temp << std::endl;  // prints 0x7fffffffde90
于 2014-03-21T16:39:06.223 回答