条款13:以对象管理资源
通常我们在定义一个函数时会出现返回一个指向某一对象指针的情况,这时就需要调用者在进行函数调用时自己管理资源。为了避免忘记释放资源的情况出现,可以考虑将资源依托到智能指针上进行管理。智能指针的优点就在于,他类似于一个对象,在出作用域时会自动调用析构函数。如下实例:
class Investment{...};
Investment* CreateInvestment(){
...
}
void f(){
std::auto_ptr<Investment> pInv(CreateInvestment());//以auto_ptr对象管理资源
...
}
void f(){
std::tr1::shared_ptr<Investment> pInv(CreateInvestment());//以ashared_ptr对象管理资源
...
}
shared_ptr和auto_ptr的区别是:shared_ptr是一个计数型智能指针,允许多个对象指向一个资源,在无人指向这个资源时会自动删除此资源。而auto_ptr只允许一个对象指向这个资源,当有新的对象指向这个资源时,旧对象会指向null。
条款16:成对使用new和delete时要采取相同形式
调用new时使用了[],必须在相应2的delete表达式中也使用[]。因为new[]表示创建多个对象,表示有多少个构造函数被调用,所以需要delete[],即析构函数被调用的次数,表示要销毁的对象的个数。如果delete,即没有加[],则并没有销毁所有对象。
同理,new未使用[]时,delete也不需要[]。假设delete加了[],则销毁了没有定义的对象。
条款17:以独立语句将newed对象置入智能指针
这里考虑的是异常case,因为编译器对一条语句内的各项操作有重新排列的权利,具体以什么形式排列视编译器情况而言,所以,假设new一个对象和将对象置入智能指针之间插入了别的操作,那么这个别的操作如果引发异常,导致程序退出,此时new好的对象还未来得及释放,就会出现内存泄漏。所以解决办法就是将newed对象置入智能指针与别的操作分离开来。如下所示:
不建议的写法:
int priority(){
...
}
processWidget(std::tr1::shared_ptr<Widget>(new Widget),priority());
建议的写法:
std::tr1::shared_ptr<Widget> pw(new Widget);
processWidget(pw,priority());
你是否还在想,为什么不考虑把new对象的过程和置入智能指针的过程分离开?其实没必要,因为置入智能指针需要对象作为参数,所以编译器会优先处理他。