分享
 
 
 

在你的代码中使用Boost智能指针(1)

王朝other·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

在你的代码中使用Boost智能指针

Smart Pointers to boost your code(By peterchen)

翻译 masterlee

Download source files - 45.3kb

正文

智能指针能够使C++的开发简单化,主要是它能够像其它限制性语言(如C#、VB)自动管理内存的释放,而且能够做更多的事情。

1、 什么是智能指针

智能指针是一种像指针的C++对象,但它能够在对象不使用的时候自己销毁掉。

我们知道在C++中的对象不再使用是很难定义的,因此C++中的资源管理是很复杂的。各种智能指针能够操作不同的情况。当然,智能指针能够在任务结束的时候删除对象,除了在程序之外。

许多库都提供了智能指针的操作,但都有自己的优点和缺点。Boost库是一个高质量的开源的C++模板库,很多人都考虑将其加入下一个C++标准库的版本中。

Boost提供了下面几种智能指针:

shared_ptr<T>

本指针中有一个引用指针记数器,表示类型T的对象是否已经不再使用。shared_ptr 是Boost中提供普通的智能指针,大多数地方都使用shared_ptr。

scoped_ptr<T>

当离开作用域能够自动释放的指针。因为它是不传递所有权的。事实上它明确禁止任何想要这样做的企图!这在你需要确保指针任何时候只有一个拥有者时的任何一种情境下都是非常重要的。

intrusive_ptr<T>

比 shared_ptr 更好的智能指针,但是需要类型 T 提供自己的指针使用引用记数机制。

weak_ptr<T>

一个弱指针,帮助shared_ptr 避免循环引用。

shared_array<T>

和 shared_ptr 类似,用来处理数组的。

scoped_array<T>

和 scoped_ptr 类似,用类处理数组的。

下面让我们看一个简单的例子:

2、 首先介绍:boost::scoped_ptr<T>

scoped_ptr 是 Boost 提供的一个简单的智能指针,它能够保证在离开作用域后对象被释放。

例子说明:本例子使用了一个帮助我们理解的类: CSample, 在类的构造函数、赋值函数、析构函数中都加入了打印调试语句。因此在程序执行的每一步都会打印调试信息。在例子的目录里已经包含了程序中需要的Boost库的部分内容,不需要下载其它内容(查看Boost的安装指南)。

下面的例子就是使用scoped_ptr 指针来自动释放对象的:

使用普通指针

使用scoped_ptr 指针

void Sample1_Plain()

{

CSample * pSample(new CSample);

if (!pSample->Query() )

// just some function...

{

delete pSample;

return;

}

pSample->Use();

delete pSample;

}

#include "boost/smart_ptr.h"

void Sample1_ScopedPtr()

{

boost::scoped_ptr<CSample>

samplePtr(new CSample);

if (!samplePtr->Query() )

// just some function...

return;

samplePtr->Use();

}

使用普通普通指针的时候,我们必须记住在函数退出的时候要释放在这个函数内创建的对象。当我们使用例外的时候处理指针是特别烦人的事情(容易忘记销毁它)。使用scoped_ptr 指针就能够在函数结束的时候自动销毁它,但对于函数外创建的指针就无能为力了。

优点:对于在复杂的函数种,使用scoped_ptr 指针能够帮助我们处理那些容易忘记释放的对象。也因此在调试模式下如果使用了空指针,就会出现一个断言。

优点

自动释放本地对象和成员变量[1],延迟实例化,操作PIMPL和RAII(看下面)

缺点

在STL容器里,多个指针操作一个对象的时候需要注意。

性能

使用scoped_ptr 指针,会增加一个普通指针。

3、 引用指针计数器

引用指针计数器记录有多少个引用指针指向同一个对象,如果最后一个引用指针被销毁的时候,那么就销毁对象本身。

shared_ptr 就是Boost中普通的引用指针计数器,它表示可以有多个指针指向同一个对象,看下面的例子:

void Sample2_Shared()

{

// (A) 创建Csample类的一个实例和一个引用。

boost::shared_ptr<CSample> mySample(new CSample);

printf("The Sample now has %i references\n", mySample.use_count()); // The Sample now has 1 references

// (B) 付第二个指针给它。

boost::shared_ptr<CSample> mySample2 = mySample; // 现在是两个引用指针。

printf("The Sample now has %i references\n", mySample.use_count());

// (C) 设置第一个指针为空。

mySample.reset();

printf("The Sample now has %i references\n", mySample2.use_count()); // 一个引用

// 当mySample2离开作用域的时候,对象只有一个引用的时候自动被删除。

}

在(A)中在堆栈重创建了CSample类的一个实例,并且分配了一个shared_ptr指针。对象mySample入下图所示:

然后我们分配了第二个指针mySample2,现在有两个指针访问同一个数据。

我们重置第一个指针(将mySample设置为空),程序中仍然有一个Csample实例,mySample2有一个引用指针。

只要当最有一个引用指针mySample2退出了它的作用域之外,Csample这个实例才被销毁。

当然,并不仅限于单个Csample这个实例,或者是两个指针,一个函数,下面是用shared_ptr的实例:

· 用作容器中。

· 用在PIMPL的惯用手法 (the pointer-to-implementation idiom )。

· RAII(Resource-Acquisition-Is-Initialization)的惯用手法中。

· 执行分割接口。

注意:如果你没有听说过PIMPL (a.k.a. handle/body) 和 RAII,可以找一个好的C++书,在C++中处于重要的内容,一般C++程序员都应该知道(不过我就是第一次看到这个写法)。智能指针只是一中方便的他们的方法,本文中不讨论他们的内容。

PIMPL:如果必须包容一个可能抛异常的子对象,但仍然不想从你自己的构造函数中抛出异常,考虑使用被叫做Handle Class或Pimpl的方法(“Pimpl”个双关语:pImpl或“pointer to implementation”)

4、 主要特点

boost::shared_ptr 有一些重要的特征必须建立在其它操作之上。

· shared_ptr<T>作用在一个未知类型上

当声明或定义一个shared_ptr<T>,T可能是一个未知的类型。例如你仅仅在前面声明了class T,但并没有定义class T。当我们要释放这个指针的时候我们需要知道这个T具体是一个声明类型。

· shared_ptr<T>作用在任意类型上

在这里本质上不需要制定T的类型(如从一个基类继承下来的)

· shared_ptr<T>支持自己定义释放对象的操作

如果你的类中自己写了释放方法,也可以使用。具体参照Boost文档。

· 强制转换

如果你定义了一个U*能够强制转换到T*(因为T是U的基类),那么shared_ptr<U>也能够强制转换到shared_ptr<T>。

· shared_ptr 是线程安全的

(这种设计的选择超过它的优点,在多线程情况下是非常必要的)

· 已经作为一种惯例,用在很多平台上,被证明和认同的。

郑重声明:

允许复制、修改、传递或其它行为

但不准用于任何商业用途.

写于 2004/11/5 masterlee

[1]、 使用scoped_ptr 指针比使用 std::auto_ptr 更能表示出指针的范围和所有权,不会混淆,或者搞得更复杂。

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有