全部博文(573)
分类: C/C++
2015-12-27 10:32:48
下面用一个简单的例子说明shared_ptr的用法:
#include #include class A { public: void print() { printf("class A print!\n"); } }; int main(int argc, char **argv) { boost::shared_ptr
shared_ptr不用手动去释放资源,它会智能地在合适的时候去自动释放。如上面的例子,a1指向的对象将会在程序结束的时候自动释放(程序结束时所有申请的资源都会被释放,这只是为了说明其作用)。再来看下面的例子:
struct data {...}; struct object { data data_; }; void f () { shared_ptr<object> o (new object); // use_count == 1 shared_ptr d (o, &o->data_); // use_count == 2 o.reset (); // use_count == 1 // When d goes out of scope, object is deleted. } void g () { typedef std::vector<object> objects; shared_ptr os (new objects); // use_count == 1 os->push_back (object ()); os->push_back (object ()); shared_ptr<object> o1 (os, &os->at (0)); // use_count == 2 shared_ptr<object> o2 (os, &os->at (1)); // use_count == 3 os.reset (); // use_count == 2 // When o1 goes out of scope, use_count becomes 1. // When o2 goes out of scope, objects is deleted. }
(1) 不要把一个原生指针给多个shared_ptr管理
int* ptr = new int; boost::shared_ptr<int> p1(ptr); boost::shared_ptr<int> p2(ptr);
这样做会导致ptr会被释放两次。在实际应用中,保证除了第一个shared_ptr使用ptr定义之外,后面的都采用p1来操作,就不会出现此类问题。
(2) 不要在函数实参里创建shared_ptr
function(shared_ptr<int>(new int), g()); //有缺陷 //可能的过程是先new int,然后调g(),g()发生异常,shared_ptr没有创建,int内存泄露 //推荐写法 shared_ptr<int> p(new int()); f(p, g());
(3) shared_ptr作为被保护的对象的成员时,小心因循环引用造成无法释放资源。
简单的例子:
class parent; class children; typedef boost::shared_ptr parent_ptr; typedef boost::shared_ptr children_ptr; class parent { public: children_ptr children; }; class children {public: parent_ptr parent; }; void test() { boost::shared_ptr father( new parent); boost::shared_ptr son(new children); father->children = son; //user_count() == 2 son->parent = father; //user_count() == 2 }
在这个例子中,出现了循环引用计数,赋值后use_count()变为2,出函数后变为1,资源无法被释放。boost的解决方法是采用 weak_ptr来保存。
class parent {public: boost::weak_ptr children; }; class children {public: boost::weak_ptr parent; };
因为boost不会影响weak_ptr不会影响引用计数,不会造成循环引用计数。
(4) 不要把this指针给shared_ptr
将this指针赋给shared_ptr会出现this指针被释放两次的危险,如下面的代码,会在t释放时析构一次,shared_ptr释放时析构一次。
class test { public: boost::shared_ptr pget() { return boost::shared_ptr(this); } }; test t; boost::shared_ptr pt = t.pget();
boost库提供的解决方法是:使用enable_shared_from_this来实现。
class test : public boost::enable_shared_from_this<test> { public: boost::shared_ptr pget() { return shared_from_this(); } }; test t; boost::shared_ptr pt = t.pget();
在新版本的C++标准中引用shared_ptr智能指针,名空间是std::tr1::shared_ptr。它和boost::shared_ptr的用法相同,在gcc4.3.x及以上的版本加选项 -std=gnu++0x即可使用。