为什么分配对象的地址在 C++ 中不变?

Why does the address of the assigned object not change in C++?

在此 C++ 示例中,class C 具有默认构造函数、复制构造函数和赋值运算符:

struct C {
    C();
    C(const C& c);
    C& operator=(const C& c);
};

实现如下,带有一些用于跟踪对象的输出。我在这些行的注释中添加了一些示例地址,作为对下面 main 程序的参考。

#include "C.h"
#include <iostream>
using namespace std;

C::C() {
    cout << "Standard constructor." << endl;
}

C::C(const C& c) {
    cout << "Copy constructor." << endl;
}

C& C::operator=(const C& c) {
    cout << "Address of reference argument: &c = " << &c << endl;      // F9B4
    cout << "Address of this: &*this =           " << &*this << endl;  // F8D4
    return *this;
}

我将使用 returns 匿名对象的工厂方法:

C foo() {
    return C();
}

现在在下面的程序中,我创建了一个命名对象 c(参见 (1))并创建了一个匿名对象 (2),我将其分配给 c (3)。我希望 c 在赋值后得到匿名对象的地址。

int main()
{
    C c;  // (1)
    cout << "Address of initial c from main: &c = " << &c << endl;                  // F8D4
    c=foo();  // (2) and (3)
    cout << "Address of initial c from main after assignment: &c = " << &c << endl; // Expected F9B4 but is F8D4
}

I expected that c then has the address of the anonymous object after the assignment.

C++ 中的对象分配在堆栈上,除非 new 明确指定。

在这种情况下,您只是创建一个临时匿名对象,然后 复制 它到 cc 在堆栈上的位置与以前相同。

您可能看不到 c=foo(); 的复制构造函数消息的原因是因为名为 copy elision 的东西,这就是我认为您认为 c 会持有匿名的原因对象,而不仅仅是它的副本。

复制赋值运算符不创建新对象,它通常更改已创建对象的数据成员。在创建对象时,为具有自动或静态存储持续时间的对象分配内存,如此声明

C c;

C++ 中的对象永远不会更改地址。

赋值运算符与任何其他方法没有什么不同,通常它只是遍历所有成员变量并为它们分配新值,从另一个对象的相应成员复制。