c++ - 奇怪的复制构造函数

标签 c++ copy-constructor copy-assignment

使用以下 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”处的对象构建的相关拷贝发生了什么?实在不明白为什么要在这里调用拷贝构造函数。


不知道我是否理解正确,所以我想进一步详细解释一下。任何人发现我的错误请指出。

首先,一张图片说明了执行流程的细节: the execution flow

(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/

相关文章:

c++ - MakeFile 中的 "undefined reference to"

c++ - std::set with std::pair - 如何为元素编写比较器

c++ - 免费(): double free detected in tcache 2 in C++

c++ - 是否推荐具有 copy-and-swap 习语和自赋值检查的复制赋值运算符?

c++ - 使用 Graphics.h 时输入

c++ - 为什么复制构造函数会有多个参数?

c++ - C++ 中隐式定义的复制构造函数是否为成员调用复制构造函数?

c++ - 在 C++ 中初始化变量的偏好

c++ - 继承加法赋值操作,如何返回正确的类型?

c++ - "QIODevice::write: device not open"文件打开时