为什么分配对象的地址在 C++ 中没有更改?

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

提问人:TMOTTM 提问时间:11/2/2020 最后编辑:Vlad from MoscowTMOTTM 更新时间:11/2/2020 访问量:578

问:

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

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

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++ memory-address assignment-operator 复制赋值

评论

1赞 drescherjm 11/2/2020
c是一个局部变量。它的地址不会改变。
1赞 PYA 11/2/2020
=只需复制内部内容即可。您无法更改堆栈上声明的变量的地址
1赞 axiac 11/2/2020
变量是一个有名字的框;它在里面存储一个值。 就是这样一个盒子; 创建并返回一个匿名框。赋值运算符不会影响框,它会将内容从一个框复制到另一个框。cfoo()=
1赞 juanchopanza 11/2/2020
我不认为一个对象的地址可以改变,无论是在堆栈上还是在免费存储上分配。
1赞 Peter - Reinstate Monica 11/2/2020
值得注意的是,如果你来自C#或Java,很容易产生这种混淆。

答:

4赞 Kostas 11/2/2020 #1

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

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

在本例中,您只需创建一个临时匿名对象,然后将其复制到 . 在堆栈上的位置与以前相同。cc

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

5赞 Vlad from Moscow 11/2/2020 #2

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

C c;
5赞 HolyBlackCat 11/2/2020 #3

C++ 中的对象从不更改地址。

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