smart pointer总结

1、C++11标准库提供两大类型的smart pointer

       shared_ptr实现共享式拥有概念。多个smart pointer既共享也拥有对象,这个拥有的意思表面上可以理解为计数器的个数。在这里特别强调是为了区分后面讲到的weak_ptr。当最后一个引用的指针被销毁时,这个对象也被析构(这里也可以理解为当计数器的个数为0时,对象被析构)。

      unique_ptr实现独占式拥有概念。保证在同一时间内只有一个smart pointer可以指向该对象。可以将移交拥有权给其他smart pointer

 

2、在这里特别提醒一点,auto_ptr成为C++11正式反对的成分。这就说明我们要避免要去使用它。

 

3、shared_ptr的声明和定义:

std::shared_ptr<string> p1{ new string(“hello”) };

std::shared_ptr<string> p2 = std::make_shared<string>(“hello”);

上面两种方式都可以,提倡用第二种方式比较快,也比较安全。

 

4、shared_ptr重置内存:

shared_ptr<string> p1;

p1 = std::make_shared<string>("hello");

p1.reset(new string("world"));

 

5、定义一个Deleter

shared_ptr<string> p1 (new string( “hello”), [ ](string* p){

cout << “Delete ” << *p << endl;

delete p;

p = nullptr});

smart pointer最后一个拥有者被销毁时,会调用这个lambda函数。

Deleter定义的必要性在于shared_ptr提供的default delete人调用的是delete,而不是delete[]。这就意味着如果使用new[]建立一个array of object,你必须定义你自己的deleter

对于这一点,unique_ptr就不一样了,它大不必如果费劲,它有一个针对array的优化,所以不用自己去定义deleter

 

6、weak_ptr的使用解决场景:

      (环式指向)。即是两个对象使用shared_ptr互相指向对方。

      (reference的指针寿命比所指对象的寿命更长)。导致访问已被释放的数据。

为什么能解决以上的场景呢?因为weak_ptr允许“共享但不拥有”某对象。 下面具体

分析weak_ptr是怎么解决的。

看下面的代码:

 

 

分析:

P1还没被赋值之前,kid对象已经被共享3次并各自拥有(划红线的地方)。就如下图画的一样,在这种情况下,当main()结束时P1也不会被释放,因为他们的计数值都不为0,于是每个Person的析构函数都从未被调用。

 

weak_ptr来解决:

 

 

分析:

使用weak_ptr之后,mom对象和dad对象都只是共享kid对象,但不拥有。同样在init之后给P1赋值,此时的计数值use_count()只是1。所以就可以避免环式指向导致泄露的问题。但有一点要注意的是,使用weak_ptr时,我们必须稍微改变访问被指对象的方式。不应该再调用:

P1->mother->kids[0]->name

现在必须在式子内加上lock():

P1->mother->kids[0].lock()->name

为什么一定要加上lock()呢?因为Mother对象内的kids保存的是weak_ptr,并不真正拥有对象,一旦外面最末拥有者在你访问的同时释放了对象,那么此时就会产生访问已经析构的对象的错误。加上lock()保证对象的存在。

 

7、std::enable_shared_from_this<>的使用:

 

但是要注意的一点是,不能在构造函数内调用shared_from_this()。因为shared_ptr本身被存放于Personbase class,也就是enable_shared_from_this<>的内部的一个private成员中,在Person构造结束之后才能被访问。

 

8、注意:shared_ptr并非线程安全。因此,当在多个线程中以shared_ptr指向同一个对象,必须使用诸如mutexlock等技术。

 

9、注意:C++11规定了编译器在函数return时会自动加上move()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值