【发布时间】:2021-06-21 23:45:59
【问题描述】:
来自“Exceptional C++”,第 27 页,作者正在谈论 Stack 的这段代码:
template< typename T>
class Stack {
public:
Stack();
~Stack();
private:
T* v_;
size_t vsize_;
size_t vused_;
};
template<typename T>
Stack<T>::Stack() :v_(0), vsize_(10), vused_(0) {
v_ = new T[vsize_];
}
template<typename T>
Stack<T>::~Stack() {
delete[] v_;
}
在第 27 页和第 28 页上,它指出当 T 的构造函数抛出时,这不会泄漏。引用本书:
其次,T 的默认构造函数,它可能会抛出任何东西,在这种情况下,任何构造的对象都会被销毁,分配的内存会自动保证通过 operator delete[])() 释放
但是,我不明白T 的析构函数和delete[] 在T 的构造函数抛出时自动调用的原因。这里没有try/catch,构造函数完成一半不会触发析构函数。我的理解是我们需要在构造函数中清理自己的烂摊子,而我认为这里没有完成。
我在我自己的 gcc10 环境中仔细检查了,我没有看到T 的析构函数在被抛出时被调用。例如,如果我使用下面的Thrower 创建堆栈,我看不到析构函数行打印。
我错过了什么吗?
int created = 0;
class Thrower {
public:
Thrower() {
if (created++ == 2) {
throw overflow_error("overflow!");
}
}
~Thrower() {
cout << "destructor called";
}
};
【问题讨论】:
-
Thrower析构函数应该有<< endl;因为不需要实现来刷新不完整的输出行 -
注意:引用并没有说你的析构函数会被调用。