c++ - 函数返回的类的析构函数

标签 c++ class g++ destructor

我有以下代码:

#include <stdio.h>

class Foo {
    public:
    int a;
    ~Foo() { printf("Goodbye %d\n", a); }
};

Foo newObj() {
    Foo obj;
    return obj;
}

int main() {
    Foo bar = newObj();
    bar.a = 5;
    bar = newObj();
}

当我用 g++ 编译并运行它时,我得到:

Goodbye 32765
Goodbye 32765

打印的数字似乎是随机的。

我有两个问题:

  1. 为什么析构函数被调用两次?
  2. 为什么不是第一次打印 5

我有 C 语言背景,因此有 printf,但我在理解析构函数、何时调用它们以及如何从函数返回类方面遇到困难。

最佳答案

让我们看看在您的主函数中发生了什么:

int main() {
    Foo bar = newObj();

这里我们只是实例化一个Foo,并用newObj()的返回值初始化它。由于copy elision,这里没有调用析构函数: 很快总结一下,obj 不是复制/移动 objbar 然后销毁 objobj 是直接在 bar 的存储中构建。

    bar.a = 5;

这里没什么好说的。我们只需将 bar.a 的值更改为 5。

    bar = newObj();

这里bar是copy-assigned1newObj()的返回值,然后析构这个函数调用创建的临时对象2,这是第一个再见。此时 bar.a 不再是 5 而是临时对象的 a 中的任何内容。

}

main()结束,局部变量被析构,包括bar,这是第二个Goodbye,不打印5 因为之前的分配。


1 由于用户定义的析构函数,这里没有发生移动赋值,没有隐式声明移动赋值运算符。
2 正如 YSC 在评论中提到的,请注意此析构函数调用具有未定义的行为,因为它正在访问此时未初始化的 abar 与临时对象的分配,特别是 a 作为其一部分的分配,出于同样的原因也具有未定义的行为。

关于c++ - 函数返回的类的析构函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56592055/

相关文章:

c++ - 使用 std::enable_if 禁用构造函数

c++ - 无法为我的非凸 QP 获得对偶值

delphi - 对象是否应该释放它所包含的对象?

java - 为什么我启动 android 时没有显示日期?

gcc - 由于不受支持的 gcc 编译器版本,Caffe 编译失败

c++ - 简单记录器实现 C++ 中的详细级别

c++ - 重复调用 - 编码练习

python - python类声明中的对象参数

c++ - 如何使用 C++11 标准使 g++ 永久编译?

c++ - 将 Matlab 与 C++ 链接时出错