您的位置:首页 > 编程语言 > C语言/C++

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

2015-03-18 15:45 316 查看

引言

众所周知,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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: