提问人:Raedwald 提问时间:10/26/2011 最后编辑:CommunityRaedwald 更新时间:11/21/2015 访问量:6308
STL 迭代器方法可能会引发异常
May STL iterator methods throw an exception
问:
析构函数可能不会引发异常(因此堆栈展开可以在异常处理期间完成),并且必须释放分配给对象的任何资源(因此不会泄漏资源)。包含多个其他对象(或分配了多个资源)的对象的设计可能会在 STL 容器中记录指向这些对象的指针。因此,析构函数将使用以下与迭代器相关的方法:
begin()
,用于容器end()
operator++
对于有效的迭代器operator*
或对于有效的迭代器operator->
但是,为了保证析构函数既不会引发异常,又会释放其资源,您需要依赖这些方法,从不引发异常。
依靠这些从不抛出异常的方法是否安全?很难想象一个实际的实现会引发异常,因为在后台,STL 迭代器本质上是一个指针。但是,标准 C++ 是否要求这些方法从不引发异常?我在 C++ 标准中没有找到明确的声明。
编辑:有趣的情况是 C++ 03 当你想要一个指向资源的指针容器时。这样做是有充分理由的;例如,如果您有多态资源。正如 Björn Pollex 在他的回答中指出的那样,如果您使用资源容器(例如 )而不是指向资源的指针容器,则容器的析构函数将为您处理对象的销毁(释放)。std::list< Resource >
Resource
答:
因此,析构函数将使用以下与迭代器相关的迭代器 方法
不,它不会。该对象的析构函数只会调用容器的析构函数,而容器的析构函数又可以保证不会引发异常。
如果正确使用 RAII,几乎不会遇到必须显式释放资源的情况。这可以通过让容器存储或 或使用 Boost.Pointer Container 之类的东西来实现。shared_ptr
unique_ptr
评论
std::vector< Resource >
std::vector< Resource * >
shared_ptr
,,Boost:我问的是标准的C++ 2003。unique_ptr
auto_ptr
返回的迭代器的复制构造函数或赋值运算符不会引发异常
这是来自C++03标准。我不认为标准比这更进一步。
顺便说一句,这是23.1.10
评论
begin() and
operator++ 表示有效的迭代器
C++标准(我指的是N3290草案)不为迭代器的增量运算符提供无抛出保证。
例如,调用 中的效果。可能调用,而这反过来可能会引发异常。std::istreambuf_iterator::operator++
std::basic_streambuf::sbumpc
sbumpc
uflow
评论
istreambuf_iterator::operator++
sbumpc
根据 http://www.tenouk.com/Module31.html 这些操作(对于“*”和“->”,它也取决于存储的类型)对于 STL 容器来说是没有的。
评论
terminate
terminate