gpt4 book ai didi

使用堆栈分配的复合对象调用两次 C++ 析构函数

转载 作者:行者123 更新时间:2023-11-30 01:36:19 25 4
gpt4 key购买 nike

我有一个复合类(包含其他实例的实例,也不是指针,也不是引用)。当容器实例被销毁时,包含实例的析构函数被调用(我同意,这是逻辑)。但问题是,如果包含的实例是堆栈分配的,则在超出范围时会再次调用析构函数。

这是编码错误还是编译器问题?

最干净的修复方法是什么?

这是我的示例:

#include <iostream>

using std::cout;
using std::endl;

class A {
public:
int i;
A(int i_) : i(i_) {
cout << "A(): " << i << endl;
}
~A() {
cout << "~A(): " << i << endl;
}
};

class B {
public:
A a;
int b;
B(const A& a_) : a(a_) {
cout << "B(): " << a.i << endl;
}
~B() {
cout << "~B(): " << a.i << endl;
}
};

int main(void) {
for(int c = 0; c < 3; ++c) {
A a(c+1);
B b(a);
cout << b.a.i << endl;
}
return 0;
}

输出是:

A(): 1
B(): 1
1
~B(): 1
~A(): 1
~A(): 1
A(): 2
B(): 2
2
~B(): 2
~A(): 2
~A(): 2
A(): 3
B(): 3
3
~B(): 3
~A(): 3
~A(): 3

编译器是 gcc 7.3.0

最佳答案

每个对象只调用一次析构函数。您在输出中看不到的是,当您构造 b 时,您使用复制构造函数(在你的案例是编译器生成的)。这不会产生任何输出,但当然也会调用拷贝的析构函数。

如果我们将输出添加到复制构造函数,我们可以看到实际发生了什么:

A(const A& a_) : i(a_.i) {
cout << "A(const A&): " << i << endl;
}

输出显示每个 A 都被复制一次,导致“重复的”(不是真的)析构函数调用 ( live demo )。如果您想避免复制对象,请查看 C++11 的 std::move,它有深入的解释 elsewhere on this site .

关于使用堆栈分配的复合对象调用两次 C++ 析构函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52425808/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com