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

问题描述

在此C ++示例中,类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;
}

我将使用一种返回匿名对象的工厂方法

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
}

解决方法

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

C c;
,

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

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

,

我希望c在赋值后具有匿名对象的地址。

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

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

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