【发布时间】:2011-12-15 16:35:13
【问题描述】:
Destructors may not throw exceptions(所以stack unwinding可以在异常处理期间完成),并且必须解除分配给对象的所有资源(所以没有资源泄漏)。包含多个其他对象(或分配了多个资源)的对象设计可能会在 STL 容器中记录指向它们的指针。因此,析构函数将使用以下与迭代器相关的方法:
-
begin(),end()用于容器 -
operator++用于有效的迭代器 -
operator*或operator->表示有效的迭代器
但要保证析构函数既不抛出异常又释放其资源,您需要依赖那些从不抛出异常的方法。
依赖那些从不抛出异常的方法是否安全?很难想象一个实际的实现会抛出异常,因为 STL 迭代器本质上是一个指针。但是标准 C++ 要求这些方法从不抛出异常吗?我在 C++ 标准中没有找到明确的声明。
编辑:当你想拥有a container of pointers to resources 时,有趣的情况是C++ 03。这样做有充分的理由;例如,如果您有多态资源。正如Björn Pollex 在他的回答中指出的那样,如果您使用资源容器(例如std::list< Resource >)而不是指向资源的指针容器,容器的析构函数将负责销毁(释放)@ 987654331@ 给你的对象。
【问题讨论】:
-
“在底层,STL 迭代器本质上是一个指针”——你永远不应该依赖这个假设。概念是基于指针,但不一定是实现。
-
析构函数可能会抛出异常,实际上......只要它们捕获它们:)。规则是“异常不能传播析构函数”。
-
规则甚至不是这样,它是“如果异常从析构函数中传播出来,程序将在某些条件下
terminate”。而且我认为它在某些条件下也可能有 UB,如果被破坏的对象是数组和/或容器的一部分,我不记得了。您是否认为terminate是您的程序可接受的消亡取决于程序,但很明显,如果您编写的组件应该易于重用,那么您会避免使用它。