这个章节主要讲的是资源管理相关的知识,C++程序中最常使用的资源就是动态分配内存,但内存只是必须管理的众多资源之一,其他常见的资源还有文件描述器、互斥锁、图形界面的字型和笔刷、数据库连接、以及网络sockets。无论是哪一种资源,重要的是,当你不再使用它时,必须将它还给系统。
条款十三
Investment* createInvestment(); //返回指针,指向Investment继承体系内的动态分配对象,调用者有责任删除它
通常调用这种factory函数,都需要在恰当的时候释放了pInv所指对象。
void f()
{
Investment* pInv = createInvestment();
...
delete pInv;
}
当很多意外的情况就会导致pInv无法释放,为了确保这一点,需要将资源放进对象中,当控制流离开f,该对象的析构函数会自动释放那些资源(把资源放进对象内,可以依赖C++的析构函数确保资源被释放)。
void f()
{
std::auto_ptr<Investment> pInv(createInvestment());
...
}
以对象管理资源的关键:
(1)获得资源后立刻放进管理对象内;
(2)管理对象运用析构函数确保资源被释放。
auto_ptr被销毁的时候会自动销毁所指的对象,所以应该要注意别让多个auto_ptr同时指向同一个对象。为了预防这个问题,auto_ptrs有一个不寻常的性质:若通过copy构造函数或copy assignment操作符复制它们,它们就会变成null,而复制所得的指针将获得资源的唯一拥有权。
std::auto_ptr<Investment> pInv1(createInvestment());
std::auto_ptr<Investment> pInv2(pInv1); // 现在pInv2指向对象,pIn1被设为null
pInv1 = pInv2; // 现在pInv1指向对象,pInv2被设为null
受auto_ptrs管理的资源必须绝对没有一个以上的auto_ptr同时指向它,这样的话STL容器就不能存放auto_ptr(STL容器要求其元素发挥正常的复制行为)。
而TR1的tr1::shared_ptr就是个RCSP:
void f()
{
...
std::tr1::shared_ptr<Investment> pInv1(createInvestment());
std::tr1::shared_ptr<Investment> pInv2(pInv1); // pInv1和pInv2指向同一个对象
pInv1(pInv2); // 同理
pInv1 = pInv2; // 同理
...
}
所以tr1::shared_ptrs可被用于STL容器等语境上。
auto_ptr和tr1::shared_ptr两者都在其析构函数内做delete而不是delete[]动作,意味着动态分配而得的array是无法使用的。一般对于动态分配数组都是使用vector和string,当然使用了Boost程序库的话,可以用boost::scoped_array和boost::shared_array。
持续更新…