智能指针模板类

智能指针模板类


什么是智能指针

智能指针是一个类对象,行为类似于指针。
智能是相对于常规指针,常规指针指向的内存,不使用时,需要调用释放函数。但经常会被遗漏或异常时没有处理,造成内存泄漏。智能指针就是为了解决此问题。智能指针对象过期时,可以在智能指针类的析构函数中释放指向的内存,实现自动释放,避免内存泄漏。

三种智能指针

  1. auto_ptr //C++98 提供的解决方案,C++11已经将其摒弃。
  2. unique_ptr
  3. shared_ptr

相对于常规指针,unique_ptr和shared_ptr的行为与auto_ptr的行为相同。
ps:不讨论智能指针weak_ptr

声明指针


#include <memory>    //需要包含头文件文件memory, 名称空间为std

auto_ptr<double> pd(new double);
auto_ptr<string> ps(new string);

unique_ptr<double> pdu(new double);
unique_ptr<string> psu(new string);

shared_ptr<double> pds(new double);
shared_ptr<string> pss(new string);

智能指针的构造函数

所有智能指针类都有一个 explicit 构造函数,表明该构造函数是显示的, 而非隐式的, 跟它相对应的另一个关键字是implicit, 意思是隐藏的,类构造函数默认情况下即声明为implicit(隐式).

构造函数将指针作为参数。声明为explicit 是为了避免错误的类型转换。

智能指针实现策略

  1. 建立所有权(ownership):只有一个智能指针可以拥有对象,释放时由拥有对象的智能指针删除该对象。赋值操作转让所有权,失去所有权的智能指针不再引用该对象。auto_ptr 和 unique_ptr 都是基于该策略, unique_ptr 的策略更加严格。
  2. 对引用计数:多个智能指针可以指向一个对象,每次引用+1,去引用时-1,计数为0时释放对象。 share_ptr 采用该策略。

unique_ptr 优于 auto_ptr

转让所有权,避免了重复删除对象的问题。转让所有权后的指针为空,试图使用会导致异常。
使用 unique_ptr 可避免这个问题。 如果避免转让所有权后还有使用的可能时,编译器会禁止该赋值行为。

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

unique_ptr<string> p3(new string("unique"));
unique_ptr<string> p4;
p4 = p3;  //编译错误  赋值后使用p3会导致异常,编译器禁止这样的赋值

只有赋值为函数返回临时 unique_ptr 或 临时右值 unique_ptr 才允许, 因为转让所有权后的unique_ptr没有机会被使用。

//函数返回临时unique_ptr
unique_ptr<string> demo(const char *s){
    unique_ptr<string> temp(new string(s));
    return temp;
}

unique_ptr<string> ps;
ps = demo("Uniquely special"); //OK

//临时右值unique_ptr
unique_ptr<string> ps;
ps = unique_ptr<string>(new string "Uniquely special"); //OK

std::move()

unique_ptr<string> p3(new string("unique"));
unique_ptr<string> p4;
p4 = p3;  //编译错误

只有赋值后,解引用p3时,才会有问题。 如果是赋予新值是不会有问题的。
编译器禁止是为了避免错误的使用p3, 如果就想执行 p4 = p3,怎么办?
使用std::move(), 可以将一个unique_ptr指针赋值给另一个。

unique_ptr 另一个好处

auto_ptr 使用的是delete, 而不是delete[]. 因此只能和new一起使用。
只有 unique_ptr 有delete[]版本。

  • 使用new 分配内存,可以使用智能指针 auto_ptr, unique_ptr, shared_ptr。
  • 使用new[]分配内存,只能使用 unique_ptr。
  • 其它方式的分配内存,不能使用智能指针。

选择智能指针

  1. 如果要多个指向同一个对象的指针,使用 shared_ptr.
  2. 如果不需要多个指向同一个对象的指针,使用 unique_ptr。
  3. 使用unique_ptr的情况都可以使用auto_ptr, 但 unique_ptr是更好的选择。
  4. STL容器中,如果有复制或复制操作,使用 shared_ptr, 没有可以使用 unique_ptr。
  5. STL容器中,unique_ptr 使用push_back() 没有问题,因为 push_back() 返回临时unique_ptr。unique_ptr 使用 for_each()不行,因为右值为非临时unique_ptr。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值