- 论坛徽章:
- 0
|
for_each(dssp.begin(), dssp.end(),
DeleteObject()); // 啊!良好定义的行为!
}
直截了当而且类型安全,正如我们喜欢的一样。
但仍不是异常安全的。如果在SpecialString被new但在调用for_each之前抛出一个异常,就会发生泄漏。那个问
题可以以多种方式被解决,但最简单的可能是用智能指针的容器来代替指针的容器,典型的是引用计数指
针。(如果你不熟悉智能指针的概念,你应该可以在任何中级或高级C++书上找到描述。在《More Effective
C++》中,这段材料在条款28。)
STL本身没有包含引用计数指针,而且写一个好的——一个总是可以正确工作的——非常需要技巧,除非必
须否则你一定不想做。我在1996年的《More Effective C++》中发布了用于引用计数智能指针的代码,尽管是
基于已制定的智能指针实现并提交给由有经验的开发人员做了很多发布前检查,小bug报告还是持续了很多
年。智能指针出错的不同方式的数量很值得注意。(详细信息请参考《More Effective C++》错误列表
[28]。)
幸运的是,基本上不需要你自己写,因为经过检验的实现不难找到。一个这样的智能指针是Boost库(参见条
款50)中的shared_ptr。利用Boost的shared_ptr,本条款的原始例子可以重写为这样:
void doSomething()
{
typedef boost::shared_ ptr<Widget> SPW; //SPW = "shared_ptr
// to Widget"
vector<SPW> vwp;
for (int i = 0; i < SOME_MAGIC_NUMBER; ++i)
vwp.push_back(SPW(new Widget)); // 从一个Widget建立SPW,
// 然后进行一次push_back
... // 使用vwp
} // 这里没有Widget泄漏,甚至
// 在上面代码中抛出异常
你不能有的愚蠢思想是你可以通过建立auto_ptr的容器来形成可以自动删除的指针。那是很可怕的想法,非
常危险。我在条款8讨论了为什么你应该避免它。
我们需要记住的所有事情就是STL容器很智能,但它们没有智能到知道是否应该删除它们所包含的指针。当
你要删除指针的容器时要避免资源泄漏,你必须用智能引用计数指针对象(比如Boost的shared_ptr)来代替 |
|