使用以下 C++ 程序:
#include <memory>
#include <iostream>
using namespace std;
struct my_class{
int value;
my_class(int id): value(id){
cout<<"constructing "<<id<<endl;
cout<<"address is "<<static_cast<const void *>(this)<<endl;
}
my_class(const my_class & a){
cout<<"construct copying "<<a.value<<endl;
cout<<static_cast<const void *>(this)<<"<-"<<static_cast<const void *>(&a)<<endl;
}
my_class operator=(const my_class & a){
cout<<"assignment copying "<<a.value<<endl;
this->value = a.value;
cout<<static_cast<const void *>(this)<<"<-"<<static_cast<const void *>(&a)<<endl;
return *this;
}
~my_class(){
cout<<"deleting "<<this->value<<endl;
cout<<"address is "<<static_cast<const void *>(this)<<endl;
}
};
my_class f(){
cout<<"==in f=="<<endl;
my_class temp(2);
cout<<"==out f=="<<endl;
return temp;
}
int main(){
cout<<"==in main=="<<endl;
my_class a(1);
a = f();
a.value++;
cout<<"==out main=="<<endl;
return 0;
}
我得到了以下结果:
====
==in main==
constructing 1
address is 0x28ff04
==in f==
constructing 2
address is 0x28ff0c
==out f==
assignment copying 2
0x28ff04<-0x28ff0c
construct copying 2
0x28ff08<-0x28ff04
deleting 2686868
address is 0x28ff08
deleting 2
address is 0x28ff0c
==out main==
deleting 3
address is 0x28ff04
===
任何人都可以向我解释地址“0x28ff08”处的对象以及从地址“0x28ff04”处的对象构建的相关拷贝发生了什么?实在不明白为什么要在这里调用拷贝构造函数。
不知道我是否理解正确,所以我想进一步详细解释一下。任何人发现我的错误请指出。
首先,一张图片说明了执行流程的细节:
(1)。创建一个值为 1 的对象 a
;
(2)。调用函数 f()
。创建一个对象temp
,编译器发现该对象会被返回,所以直接在调用者的栈中创建;
(3)。通过调用 operator=()
将 f()
的返回对象(即 temp
)分配给对象 a
一个
;
(4)。对象 a
使用相同的变量名 a
作为参数(右值)传递到 operator=()
。
(5)。 operator=()
方法在 main::a
上调用(左值,滥用符号),因此 this
在函数点到 main::a
,[!!这是让我困惑的部分];
(6)。 operator=()
将 main::a
的值更改为 a
的值(即从 1 到 2);
(7)。编译器发现返回类型不是引用,而*this
已经存在于main()
中,所以不得不复制*this
通过调用复制构造函数。然而,拷贝构造函数并没有初始化对象,所以创建了一个未初始化的对象。
(8)。 [!!不太确定这部分]左值和结果对象是同一个对象,因此由于优化没有真正返回对象。
(9)。复制的对象被销毁,根据@Mike Seymour 的说法,这个对象被创建是因为编译器不能省略它,因为构造函数和析构函数实际上都做了一些事情(例如输出值和地址)。
(10)。当退出 operator=()
时,对象 a
被销毁。
(11)。当退出 main()
时,对象 main::a
最终被销毁。
上面解释了输出,但是,我目前的理解可能不正确。如果我错了,请帮助我理解这一点。非常感谢。
最佳答案
这是因为您的赋值运算符返回对象的拷贝。这里:
my_class operator=(const my_class & a)
改用引用:
my_class& operator=(const my_class & a)
关于c++ - 奇怪的复制构造函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13990215/