C++学习笔记之智能指针

引言

众所周知,C++中最让程序员头疼的就是关于内存的问题,其中不外乎以下几点:
1. 缓冲区溢出
2. 野指针
3. 重复释放内存
4. 不配对的new/delete
5. 内存泄露
其中大多数的问题都是对指针的不正确使用带来的。为此C++标准库中对原始指针做了一些封装,比如auto_ptr,使得指针更容易使用,但是还是存在众多不足。而在Boost库中,对原始指针做了更多的封装,弥补了auto_ptr的不足,所以下面介绍的是Boost库中的几个智能指针。

scoped_ptr

定义:类似于auto_ptr的智能指针,它包装了new操作符在堆上分配的动态对象,能够保证动态创建的对象在任何时候都可以被正确地删除,只能在被声明的作用域内使用。
用法

#include <boost/smart_ptr.hpp>
using namespace boost;
scoped_ptr<string> sp(new string("text"));

与auto_ptr的区别:scoped_ptr的所有权更加严格,一旦scoped_ptr获取了对象的管理权就不能转让出去了(因为拷贝构造函数和赋值操作符都被声明为私有)。而auto_ptr的所有权可以转让,比如:

auto_ptr<string> ap(new string("test");
scoped_ptr<string> sp1(ap);  // ap已经把所有权让给sp1了。
scoped_ptr<string> sp2 = sp1; // 编译错误,sp1的所有权不能转让。

scoped_array

定义:类似于scoped_ptr,但它包装了new[]操作符在堆上分配的动态数组,为动态数组提供了一个代理,保证可以正确地释放内存。它也不能拷贝、赋值。只能在被声明的作用域内使用。
用法

#include <boost/smart_ptr.hpp>
using namespace boost;
scoped_array<int> sa(new int[100]);

不足
1. scoped_array重载了[]操作符,所有可以像数组一样用[]获取索引处的值,但是它并没有提供数组范围的检查,超出索引会引发未定义的行为发生。
2. 不能动态增长,也没有迭代器支持,不能搭配STL算法。
建议:要使用数组语意时,不推荐用scoped_array,而应该用vector,它支持动态增长,且有丰富的成员函数来操纵数据。

shared_ptr

定义:shared_ptr是一个最像指针的“智能指针”,它和scoped_ptr一样,包装了new操作符在堆上分配的动态对象,但它实现的是引用计数型的智能指针,可以被自由的拷贝和赋值,在任意的地方共享它。
用法

#include <boost/smart_ptr.hpp>
using namespace boost;
shared_ptr<int> sp(new int(10));

另类用法
1. 工厂函数,不需要调用new关键字
#include <boost/make_shared.hpp>
shared_ptr<string> sp = make_shared<string>("make_shared");
shared_ptr<string> spv = make_shared<vector<int>>(10,2);

2. 定制删除器
shared_ptr(Y *p, D d)用于在析构时调用d方法来操作p指针,即调用d(p)。比如,在释放套接字时候,调用关闭套将字的方法:shared_ptr(socket,close);
3. 其他一切用到指针的设计模式

shared_array

定义:类似于shared_ptr,但包装了new[]操作符,同样使用了引用计数。
用法

int *p = new int[100];
shared_array<int> sa1(p);
shared_array<int> sa2 = sa1;

注意:shared_array重载的[]不提供数组索引的范围检查。建议使用shared_ptr或std::vector。

weak_ptr

定义:为了配合shared_ptr而引入的一种智能指针,它更像一个助手,它不具备普通指针的行为它的最大作用在于协助shared_ptr工作。它没有重载operator*和->,这是特意的,因为它不共享指针,不能操作资源。
用法

shared_ptr<int> sp(new int(10));
weak_ptr<int> wp(sp);
if ( !wp.expired() )  // 判断wp观察的对象是否失效
{
    shared_ptr<int> sp2 = wp.lock();  // 获得一个shared_ptr
    *sp2 = 100;
}

猜你喜欢

转载自blog.csdn.net/LYH66/article/details/44411401