pInv1 and pInv2 now
pInv2(pInv1); // point to the object
pInv1 = pInv2; // ditto - nothing has
// changed
...
} // pInv1 and pInv2 are
// destroyed, and the
// object they point to is
// automatically deleted
因为拷贝 tr1::shared_ptrs 的工作“符合预期”,它们能被用于 STL 容器以及其它和 auto_ptr 的非正统的拷贝行为不相容的环境中。
不要搞错,本文不是关于 about auto_ptr,tr1::shared_ptr 或任何其它种类的智能指针。而是关于使用对象管理资源的重要性的。about auto_ptr 和 tr1::shared_ptr 仅仅是做这些事的对象的例子。(关于 tr1::shared_ptr 的更多信息,请参考 Item 14,18 和 54。)
std::auto_ptr // bad idea! the wrong
aps(new std::string[10]); // delete form will be used
std::tr1::shared_ptr spi(new int[1024]); // same problem 你可能会吃惊地 发现 C++ 中没有可用于动态分配数组的类似 auto_ptr 或 tr1::shared_ptr 这样的东西,甚至在 TR1 中也没有。那是因为 vector 和 string 几乎总是能代替动态分配数组。如果你依然觉得有可用于数组的类似 auto_ptr 和类似 tr1::shared_ptr 的类更好一些的话,可以去看看 Boost。在那里,你将高兴地找到 boost::scoped_array 和 boost::shared_array 两个类提供你在寻找的行为。 本 Item 的关于使用对象管理资源的指导间接表明:如果你手动释放资源(例如,使用 delete,而不使用资源管理类),你就是在自找麻烦。像 auto_ptr 和 tr1::shared_ptr 这样的预制的资源管理类通常会使本文的建议变得容易,但有时,你使用了一个资源,而这些预加工的类不能如你所愿地做事。如果碰上这种情况,你就需要精心打造你自己的资源管理类。那也并非困难得可怕,但它包含一些需要你细心考虑的微妙之处。
作为最后的意见,我必须指出 createInvestment 的未加工指针的返回形式就是资源泄漏的请帖,因为调用者忘记在他们取回来的指针上调用 delete 实在是太容易了。(即使他们使用一个 auto_ptr 或 tr1::shared_ptr 来完成 delete,他们仍然必须记住将 createInvestment 的返回值存储到智能指针对象中。)对付这个问题需要改变 createInvestment 的接口。
Things to Remember
为了防止资源泄漏,使用 RAII 对象,在 RAII 对象的构造函数中获得资源并在析构函数中释放它们。
两个通用的 RAII 是 tr1::shared_ptr 和 auto_ptr。tr1::shared_ptr 通常是更好的选择,因为它的拷贝时的行为是符合直觉的。拷贝一个