一、Boost使用基础

Boost库的大部分组件(90%左右),不需要进行编译,直接包含头文件即可使用。
#include <boost/logic/tribool.hpp>
using namespace std;

Boost网站

www.boost.org

C++标准库的一个实现——STLport

配合boost库工作
可移植性高,几乎可以配合市面上所有的操作系统合编译器来使用

如果想要深入了解,推荐大家看一下《Boost完全开发手册这本书》,虽然是十年前的老书,但有诸多可以复用的经验,读后使人受益匪浅。

二、内存管理

由于指针的灵活性与复杂性,C++在使用指针不当时,会导致内存泄漏、野指针、访问越界等一系列的问题。
C++提供了auto_ptr智能指针,但仍有不足。
boost库中提供了想java垃圾回收机制一样的一套高效的管理内存方式。

1. Smart_prt库

1.1 RALL机制

在使用资源的类的构造函数中申请资源,在相应的析构函数中释放资源。
在声明栈上局部变量时申请的资源,可以在离开作用域后自动释放,而使用new申请的资源,需要程序员显式的进行相应的delete操作才能释放,这就造成了内存泄漏的安全隐患。

1.2 智能指针

在退出作用域时,不管是正常退出还是异常退出,都自动调用delete释放在堆中动态申请的资源。
智能指针有很多种,例如:

std::auto_prt
  1. return 之前调用delete
  2. catch异常之后,调用delete
int main()
{auto_ptr < class_need_resource > p1 (new class_need_resource);auto_ptr <demo_class> p2(demo_class.creat());
}   // 离开作用域后,p1,p2自动析构,释放占用的内存空间

遗憾的是,C++标准库并没有覆盖智能指针的全部领域,特别是引用计数型智能指针。

1.3 boost对智能指针的实现

boost.smart_ptr库是对C++98标准的一个绝对补充,包含了六种智能指针:

  1. scoped_ptr
  2. scoped_array
  3. shared_ptr
  4. shared_array
  5. weak_ptr
  6. instrusive_ptr

以上六种智能指针,都是轻量级的组件,速度与原始指针相差无几,对于所指向的类型T也仅有一个很小且很合理的要求:类型T不能抛出异常。

如何使用:

include <boost/smart_prt>
using namespace boost;

2. scoped_ptr

2.1 基本介绍

类似auto_ptr的智能指针,保证动态创建的对象在任何时候都能被正确的删除。

scoped_ptr的所有权限制更加严格,不能转让,一旦scoped_ptr获得了对象的所有权,你就不能从它那里收回来。

scoped_ptr同时把拷贝构造函数和赋值操作符都声明为私有,禁止对指针的赋值操作,保证了它管理的指针不能被转让所有权。

成员函数reset的功能是重置scope的_ptr,这违背了设计的初衷。
非必须的情况下,尽少使用这种用法。

scoped_ptr重载了运算符*和运算符->,来模仿被代理的原始指针的行为,便于将Scoped_ptr对象如同原始指针对象一样来使用。如果,scoped_ptr保存了空指针,则此行为未定义。

scoped_ptr指针不能进行比较操作,因为==和!=运算符都已经被声明为私有,但是提供了一种在bool语境中自动转化为bool值的用法,通过这一用法可以判断指针是否为空。

成员函数swap用来交换两个指针的值,操作高效,被用于实现reset函数。

成员函数get用来返回此局部指针所对应的原始指针,一般用于如底层是C语音必须需要原始指针的场景等。
注意,千万不要对返回的指针进行delete操作。
否则,程序会面临崩溃的危险。

2.2 与auto_ptr的对比

scoped_ptr和auto_ptr的用法基本一致,大多数情况下可以相互替换,它可以从auto_ptr获得指针的管理权——同时auto_ptr失去指针的管理权。

与auto_ptr一样,两者都不能用作容器的元素,不过原因不同。
auto_ptr是因为它的转移语义,而scoped_ptr是因为他不能拷贝和赋值,不符合容器对元素的要求。

auto_ptr的指针所有权是可以转移的,可以在函数间传递,同一时刻只能有一个auto_ptr来进行管理。

而scoped_ptr因为私有化了赋值和拷贝操作,指针所有权不能转移。

3.scoped_array

scoped_array弥补了标准库中没有指向数组的智能指针的遗憾。

基本介绍

构造函数接受的指针必须是new【】的结果
重载了【】运算符,可以像普通数组一样使用下标访问元素,但越界时会发生意想不到的错误。
但不能使用*和->运算符,因为没有定义。

只能在声明的作用域内使用,不能拷贝和赋值。

由于并未定义很多操作,使用scoped_array与使用正常数组速度一样快,但是不能作为函数和容器等的接口,也不能动态增长。

因此,如果要使用动态数组的话,尽量使用std::vector,它只引入了很小的开销,提供了更高的安全性和灵活性。

4. shared_ptr

4.1 与scoped_ptr的比较

shared_ptr是最像指针的智能指针,是boost.smart_ptr库中,最有价值、最重要的组成部分。

引用计数型的智能指针,可以被自由的拷贝和赋值,在任意的地方共享它,当没有代码使用它(引用计数为0时),才自动删除被包装的对象。

shared_ptr可以安全的放到标准的容器中,作为容器的元素。

shared_ptr与scoped_ptr一样都是管理new动态分配对象的智能指针,因此功能上有许多的相似之处。

  1. 他们都重载了*和->操作符,以模仿原始指针的行为
  2. 都隐式的提供bool类型转换,以判断指针的有效性
  3. get可以得到原始指针
  4. 都没有提供指针运算操作

shared_ptr不但有正常的赋值与拷贝语义,而且可以进行比较操作。

4.2 基本介绍

构造函数

无参数的shared_ptr创建一个持有空指针的shared_ptr。

shared_ptr(Y * p) 获得指向类型T的p指针的管理权,同时引用计数置为1。
其中类型Y必须能转化为类型T。

shared_ptr ( shared_ptr const & r), 从另一个shared_ptr获得指针的管理权,同时引用计数加1,结果是两个shared_ptr指针共享一个指针的管理权。

shared_ptr(std::auto_ptr < Y > & r),从一个auto_ptr获得指针的管理权,引用计数置为1,同时auto_ptr失去指针的管理权。

“=” 赋值运算符,对于对象shared_ptr和auto_ptr,结果同构造函数。

当然,还有特殊的shared_ptr(Y * p,D d),第二个参数指定了析构时的一些特性,之后再做介绍。

reset()

对于不带参数的reset(),效果是让引用数减1.

带参数的reset()函数在原指针引用计数减1的同事,改为管理另一个指针,效果类比同样形式的构造函数。

引用计数

unique()返回当前指针是否引用了,如果引用了,则返回true,否则,返回false,高效操作。

use_count() 较为低效率的操作,返回计数引用的指针数量,甚至有时候是不可用的。

比较运算

比较运算基于内部的指针,如a.get() == b.get().

还提供了唯一可以使用的比较运算符 " < ",因为提供了 " < " 操作,因此可以被用于某些内部的容器,比较set和map等等。

类型转换

在编写基于虚函数的多态代码时,指针的类型转换很重要,比如把一个基类指针转化为一个子类的指针,或者反过来。

但是对于shared_ptr不能使用诸如

static_cast<T*> (p.get())

的形式。
而要使用:

static_pointer_cast<T> ()
const_pointer_cast<T> ()
dynamic_pointer_cast<T> ()

分别对应标准的转型操作符:

static_cast<T> ()
const_cast<T> ()
dynamic_cast<T> ()

但以上操作符返回的类型都是shared_ptr。

4.3 使用工厂模式

#include <boost/make_shared.hpp>

make_shared()函数可以接收最多十个参数,然后把他们传递给类型T的构造函数,创建一个shared_ptr对象并返回。

make_shared()函数要比直接创建shared_ptr对象的方式更为高效,因为他内部仅仅分配了一次内存,消除了shared_ptr构造时的开销。

举个栗子

#include <vector>#include <boost/smart_ptr.hpp>
#include <boost/make_shared.hpp>using namespace boost;int main()
{shared_ptr<string> sp = make_shared<string>("Hello make_shared make me.");shared_ptr<std::vector<int> > sp_vector = make_shared<std::vector<int> > (10, 2);assert(spv->size() == 10);
}

4.4 使用桥接模式

简要介绍

桥接模式(bridge)是一种结构型的设计模式,把类之间的具体实现细节隐藏起来,以达到最小耦合的目的。
在具体实践中,桥接模式也被称为pimpl或者handle/body惯用法,可以将文件的依赖关系降到最小,减少编译时间,可以不利用虚函数便能实现多态。

删除器

举个栗子

shared_ptr<FILE> fp(fopen("./try.txt", 'r'), fclose);

当离开作用域时,shared_ptr自动调用fclose来关闭文件。

4.5 shared_array

用法如同scoped_ptr,可以考虑更为安全的vecto,这里不做详细介绍。

5. weak_ptr

5.1 基本介绍

协助shared_ptr使用,像旁观者一样观测资源的使用情况。

weak_ptr不影响引用计数。

5.2 获得this的shared_ptr

获取this指针的shared_ptr,使对象产生shared_ptr对象管理自己。

对象使用weak_ptr观测this指针,不影响计数,在需要的时候调用lock()函数返回shared_ptr供外界使用。

简要介绍如上,如果要深入了解的话,可以继续翻阅书籍的相关章节。

6. intrusive_ptr

6.1 基本介绍

侵入式的引用计数型指针,用于如下场景:

  1. 对内存占用的要求非常严格,要求与原指针一样。
  2. 现存代码已经有了引用计数机制的对象

应用较少,只做简要介绍,如果需要的时候,再去深入学习。

Boost学习笔记(一)——Boost使用基础、内存管理相关推荐

  1. (实验37)单片机,STM32F4学习笔记,代码讲解【内存管理实验】【正点原子】【原创】

    文章目录 其它文章链接,独家吐血整理 实验现象 主程序 内存池初始化程序 代码讲解 其它文章链接,独家吐血整理 (实验3)单片机,STM32F4学习笔记,代码讲解[按键输入实验][正点原子][原创] ...

  2. .NET深入学习笔记(3):垃圾回收与内存管理

    今天抽空来讨论一下.Net的垃圾回收与内存管理机制,也算是完成上个<WCF分布式开发必备知识>系列后的一次休息吧.以前被别人面试的时候问过我GC工作原理的问题,我现在面试新人的时候偶尔也会 ...

  3. 《Go语言圣经》学习笔记 第三章 基础数据类型

    <Go语言圣经>学习笔记 第三章 基础数据类型 目录 整型 浮点数 复数 布尔型 字符串 常量 注:学习<Go语言圣经>笔记,PDF点击下载,建议看书. Go语言小白学习笔记, ...

  4. JDBC 学习笔记(一)—— 基础知识 + 分页技术

    2019独角兽企业重金招聘Python工程师标准>>> 本文查阅方法:     1.查阅目录 -- 查阅本文目录,确定想要查阅的目录标题     2.快捷"查找" ...

  5. MATLAB学习笔记2:MATLAB基础知识(下)

    阅读前请注意: 1. 该学习笔记是华中师范大学HelloWorld程序设计协会2021年寒假MATLAB培训的学习记录,是基于培训课堂内容的总结归纳.拓展阅读.博客内容由 @K2SO4钾 撰写.编辑, ...

  6. 学习笔记【Java 虚拟机④】内存模型

    若文章内容或图片失效,请留言反馈.部分素材来自网络,若不小心影响到您的利益,请联系博主删除. 总目录 学习笔记[Java 虚拟机①]内存结构 学习笔记[Java 虚拟机②]垃圾回收 学习笔记[Java ...

  7. Dram学习笔记(2) 读《终极内存技术指南》笔记 + 纠正一些流传很广的文章错误

    文章目录 0. 引言 1. Dram 名词解释 2. 一些流程步骤的梳理 2.1 内存结构 2.2 一次burst的实现 2.3 一次mask burst的实现 3. 不懂的地方 3.1 数据在内存里 ...

  8. arduino 学习笔记及课件01基础入门

    arduino 学习笔记及课件01基础入门 以下学习笔记中图片部分由太极创客视频截图所得 概论 一. 引脚及信号 1.1引脚模式 INPUT:当Arduino没有使用上拉电阻或下拉电阻而直接与开放的开 ...

  9. J2EE学习笔记三:EJB基础概念和知识 收藏

    J2EE学习笔记三:EJB基础概念和知识 收藏 EJB正是J2EE的旗舰技术,因此俺直接跳到这一章来了,前面的几章都是讲Servlet和JSP以及JDBC的,俺都懂一些.那么EJB和通常我们所说的Ja ...

  10. 梓益C语言学习笔记之链表&动态内存&文件

    梓益C语言学习笔记之链表&动态内存&文件 一.定义: 链表是一种物理存储上非连续,通过指针链接次序,实现的一种线性存储结构. 二.特点: 链表由一系列节点(链表中每一个元素称为节点)组 ...

最新文章

  1. Android Studio 配置虚拟设备的镜像文件的存放路径
  2. Tornado推出2.0版
  3. 第7步 mybatis-generator dao层生成器
  4. 程序员:如何写出杀手级简历
  5. 2019阿里云618大促主会场全攻略
  6. push本地代码到github出错
  7. 建筑施工承插型盘扣式钢管支架安全技术规程_承插型盘扣式钢管支架施工技术交底(视频教程)...
  8. pycharm的项目文件中包括什么_一个完整的项目管理流程包括什么?
  9. bootstrap table border粗细_Web前端开发(18)——Bootstrap响应式布局
  10. Sublime Text 3中SublimeLinter的使用
  11. 微信好友检测助手App
  12. python做词云统计_python词频统计,生成词云
  13. 《JavaScript函数式编程思想》——从面向对象到函数式编程
  14. pentaho安装配置
  15. java判断闰年中闰月_农历中闰年闰月的算法
  16. DOSBOX——DEBUG的简单使用
  17. 四川大学计算机学院硕士毕业要求,四川大学计算机学院(软件学院)2020年非全日制硕士研究生接受调剂生的通知...
  18. bootstrap入门步骤
  19. 最大子段和(java)
  20. 贴片功率电感封装尺寸与性能

热门文章

  1. python输出一个月日历表_Python实例教程之检索输出月份日历表
  2. 苹果与京东合推“京享无忧”,服务能否成手机竞争分水岭?
  3. Java毕设项目电费管理系统(java+VUE+Mybatis+Maven+Mysql)
  4. 弘易信泰,SAAS安全性策略解读
  5. 【塔望咨询】×【颐海国际】筷手小厨 自热米饭全新打造上线
  6. Vue+vant实现移动端记住密码功能
  7. LED原理及流水灯的实现
  8. 在项目管理中,如何避免出现低级错误?| 每天成就更大成功
  9. iPhone用户干货:袋鼠下载,如何导出已下载的视频到其他播放器?
  10. 阿里云ACP企业级互联网架构ACP实验之本地配置EDAS开发环境