【发布时间】:2019-02-24 19:20:29
【问题描述】:
我有一个复合类(包含其他实例、指针和引用的实例)。 当容器实例被销毁时,将调用包含实例的析构函数(我可以接受,这是逻辑)。但问题是,如果包含的实例是堆栈分配的,则在超出范围时会再次调用析构函数。
这是编码错误还是编译器问题?
最干净的修复方法是什么?
这是我的示例:
#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 .... 它只是没有调用你认为它应该调用的构造函数
-
您已经知道
~B调用~A。但是除了B的实例之外,您还有另一个A的免费实例。所以A的两个实例:一个免费,一个在B内部。两者的析构函数都被调用。 -
为什么觉得这里有问题?
-
在跟踪构造函数/析构函数调用时,不要忘记复制/移动构造函数。
标签: c++ destructor