admin 管理员组

文章数量: 887007

智能指针管理通过new创建的对象

来自《编写高质量代码:改善C++程序的150个建议》读书笔记

1.auto_ptr

指向一个以new建立的对象,当auto_ptr的生命周期结束时,其所指向的对象之资源也会被自动释放,且不必显示地调用delete。

#include <memory>
using namespace std;
class A
{
public:A() {}~A(){}void Hello(){cout << "Hello Smart Pointer";}
};
int main()
{auto_ptr<A> pA(new A());pA->Hello();auto_ptr<int> iPtr; // 未指向任何对象,像空指针if(iPtr.get()==0) // 不指向任何对象判断{iPtr.reset(new int(2011));}auto_ptr<string> sPtr1(new string("Smart Pointer"));auto_ptr<string> sPtr2(sPtr1); // 所有权转移if (!sPtr1->empty())  // 判断emptry时程序会崩溃cout << *sPtr1 << endl;return 0;
}

auto_ptr的资源维护动作是以inline的方式来完成的,在编译时代码会被扩展开来,所以使用它并不会牺牲效率。
缺点:

  • auto_ptr对象不可作为STL容器的元素
  • auto_ptr缺少对动态配置而来的数组的支持;
    auto_ptr<char> pstr(new char[12]); //不支持
    不管什么时候使用数组的new操作时,必须要用delete[]来摧毁数组。因为auto_ptr的析构函数只对非数组类型起作用。所以数组是不能被正确摧毁的话,程序的行为是不明确的。
  • auto_ptr在被复制时会发生所有权转移

2011年9月C++新标准C++11中废弃了auto_ptr指针,取而代之的是两个新的指针类:shared_ptr和unique_ptr。shared_ptr是引用计数指针,unique_ptr是用来取代auto_ptr的,提供了auto_ptr的大部分特性,唯一例外的是auto_ptr的不安全、隐性的左值搬移。

2.Boost中的智能指针

在Boost中的智能指针有五种:scoped_ptr、scoped_array、shared_ptr、shared_array、weak_ptr,其中最有用的就是shared_ptr,采用了引用计数,并且是线程安全的,同时支持扩展。
boost::shared_ptr支持STL容器:

typedef boost::shared_ptr<string> CStringPtr;
std::vector<CStringPtr> strVec;
strVec.push_back(CStringPtr(new string("Hello")));

Boost智能指针同样支持数组,boost::scoped_array和boost::shared_array对象指向的是动态配置的数组。

3.使用智能指针也应该遵守的规则

规则1:Smart_ptr<T>不同于T*,前者身份是一个对象,后者是指向T类对象的指针,不能盲目地将T*和智能指针类型Smart_ptr<T>相互转换。

  • 在创建一个智能指针时需明确写出Smart_ptr<T> tPtr(new T)。
  • 禁止将T*赋值给一个智能指针。
  • 不能采用tPtr=NULL的方式将tPtr置空,应该使用智能指针类的成员函数。

规则2:不要使用临时的shared_ptr对象

class A;
bool IsAllReady();
void ProcessObject(boost::shared_ptr<A> pA, bool isReady);
ProcessObject(boost::shared_ptr(new A), IsAllReady());

调用ProcessObject函数前,C++编译器要完成三件事:

  1. 执行”new A”。
  2. 调用boost::shared_ptr的构造函数。
  3. 调用函数IsAllReady()。

因为函数参数求值顺序的不确定性,如果调用IsAllReady()发生在1、2之间,而又正好出现异常,那么new A得到的内存返回的指针就会丢失,进而发生内存泄漏,因为返回的指针没有存入我们原来期望能阻止资源泄漏的boost::shared_ptr上。避免这种问题的方式,就是不要使用临时的shared_ptr对象,改用局部变量来实现。

本文标签: 智能指针管理通过new创建的对象