C++智能指针

参考资料:《C++ Primer Plus中文版 第六版》
智能指针定义:
行为类似于指针的类对象,但这种对象还有其他功能。重要的区别是他负责自动释放所指向的对象。

引入智能指针的原因:
在C++中,动态内存分配使用new、delete或new[]、delete[]创建和销毁,但会出现使用new或new[]创建动态内存后,忘记使用delete或delete[]或在使用delete之前程序异常终止,造成内存泄露。或者在还有指针引用该内存时提前使用delete释放内存,会产生引用非法内存指针问题。为此,C++11提出了智能指针概念。

智能指针模板类:
可帮助管理动态内存的智能指针模板有:auto_ptr、unique_ptr、share_ptr和weak_ptr;这四个智能指针模板都定义了类似指针的对象,可以将new获得的地址赋给这种对象,当智能指针过期时,其析构函数将使用delete来释放内存。

#include <memory>
void remodel(std::string & str)
{
    std::auto_ptr<std::string> ps (new std::string(str));
    ...
    if(weird_thing())
        throw exception();
    str = *ps;
    return;
}

auto_ptr
模板auto_ptr是C++98提供的解决方案,C++11已将其摒弃.

auto_ptr<string> ps (new string("I reigned lonely as a cloud."));
auto_ptr<string> vocation;
vocation = ps;

如果ps和vocation是常规指针,则两个指针将指向同一个string对象,当ps过期时,程序将释放该对象,但是vocation过期时,程序也将释放这个对象,要避免这种问题,方法有多种:
1、定义赋值运算符,使之执行深复制,这样两个指针将指向不同的对象,其中的一个对象是另一个对象的副本。
2、建立所有权概念,对于特定的对象,只能有一个智能指针可拥有它,这样只有拥有对象的智能指针的构造函数会删除对象。然后,让赋值操作转让所有权。这就是用于auto_ptr和unique_ptr的策略。但unique_ptr的策略更严格。
3、创建智能更高的指针,跟踪引用特定对象的智能指针数,这称为引用计数,赋值时,技术将加1,而指针国旗时,计数将减1。仅当最后一个指针过期时,才调用delete。这是share_ptr采用的策略。

unique_ptr为何优于auto_ptr

auto_ptr<string> p1(new string("auto");
auto_ptr<string> p2;
p2 = p1;

p2接管string对象的所有权后,p1的所有权被剥夺,但如果程序随后试图使用p1时程序可能会出现崩溃现象。

unique_ptr<string> p3 = new string("auto");
unique_ptr<string> p4;
p4 = p3;   //ERROR

该段程序在编译的时候报错,避免了p3不再指向有效数据的问题,因此,unique_ptr比auto_ptr更安全。
相比于auto_ptr和share_ptr,unique_ptr有可用于数组的变体。

std::unique_prt<double[]> pda(new double(5)); 

weak_ptr
weak_ptr解决了share_ptr循环引用的问题,它是一种不控制所指向对象生存期的智能指针,不能直接将它用来定义一个智能指针,智能配合share_ptr。将一个weak_ptr绑定到一个shared_ptr不会改变shared_ptr的引用计数。一旦最后一个指向对象的shared_ptr被销毁,对象就会被释放,即使有weak_ptr指向对象,对象还是会被释放。

选择智能指针
如果程序要使用多个指向同一个对象的指针,应选择share_ptr。
如果程序不需要多个指向同一个对象的指针,则可使用unique_ptr。
如果程序不适用new或new[]分配内存时,则不能使用unique_ptr。
如果程序不使用new分配内存,则不能使用auto_ptr和share_ptr。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值