一 以对象管理资源:
(1)RAII(Resource Acquisition Is Initialization):资源取得时即初始化。例如:auto_ptr和shared_ptr等(详见智能指针文章)。
(2)为防止资源泄漏,请使用RAII对象,它们在构造函数中获得资源并在析构函数中释放资源。
二 在资源管理类(自己定义的)中小心copying行为:
(1)并非所有资源都是heap-based的,对于这些资源auto_ptr和shared_ptr往往不适合作为资源管理者,这是需建立自己的资源管理类。
(2)当一个对象被复制时,多数发生如下情况:
*使用引用计数法(如:shared_ptr)。
*转移底部资源拥有权(如:auto_ptr)。
*深拷贝(复制底部资源,无对应的RAII对象)。
*禁止复制(将copying操作声明为private,如scoped_ptr)。
三 在资源管理类中提供对原始资源的访问:
(1)RAII对象(auto_ptr和shared_ptr)都提供对原始资源的访问方法:
*显示访问:get()成员返回智能指针内部的原始指针(的复件)
*隐式访问:tr1::shared_ptr和auto_ptr也重载了指针取值操作符:operator ->和operator *。
(2)自己定义的资源管理类也可以提供get成员函数提供显示转换,或重载()提供隐式转换函数。
*一般而言,显示转换比较安全;但隐式转换对客户比较方便。
四 成对使用new和delete时要采取相同形式:
*如果你在new表达式中使用[],必须在相应的delete表达式中也使用[]。
五 以独立语句将newd对象置入智能指针:
(1)以独立语句将newd对象存储于智能指针内,否则,一旦异常抛出可能导致难以察觉的资源泄漏。
例如:
func(tr1::shared_ptr<Base> ptr(new Base),fun1());
*在调用func必须做三件事:调用fun1();执行new Base;调用tr1::shared_ptr构造函数。
*c++以什么次序完成上面三件事,弹性很大,只能确定new Base在调用tr1::shared_ptr构造函数之前。
*如果按照下列次序:new Base;fun1();调用tr1::shared_ptr构造函数。万一fun1调用导致异常,可能导致资源泄漏。
*比较好的写法:
tr1::shared_ptr<Base>ptr(new Base);
func(ptr,fun1())。