smart_ptr

  • raii ( Resource Acquisition Is Initialization )
  • 智能指针系列的都统称为smart_ptr。包含c++98标准的auto_ptr
  • 智能指针是一个类,通过重载->和*完毕相似原始指针的操作。

    只是由于是类,所以能够做比方内存管理、线程安全之类的工作

  • 智能指针均是自己主动管理内存,不须要显示调用delete

scoped_ptr

  • 与auto_ptr最大的不同,是私有化构造和拷贝构造,使操作权不能转让,所以有强作用域属性,并且指针类自己负责释放
  • 与c++11标准的unique_ptr相比:unique_ptr有很多其它功能,能够像原始指针一样进行比較、像shared_ptr一样定制删除器,也能够安全地放入标准容器。可是少即是多。scope_ptr专注于强调作用域属性。

scoped_array

  • 与scoped_ptr相似,仅仅只是封装的是new[]分配数组。
  • 不是指针。也就没有实现*和->的重载,而是直接[]下标訪问
  • 通常不建议使用scoped_array。它的出现通常往往意味着你的代码中存在着隐患

shared_ptr(重点)

  • boost.smart_ptr中最有价值、最重要的组成部分,也最经经常使用
  • unique()在shared_ptr是指针中唯一全部者时返回true
  • user_count()返回当前指针的引用计数
  • 提供operator<、==比較操作 。使shared_ptr能够被用于set/map标准容器
  • 编写多态指针时。不能使用诸如static_cast< T* >(p.get())的形式。这将导致转型后的指针无法再被shared_ptr正确管理。为了支持这种使用方法,shared_ptr提供内置的转型函数static_pointer_cast< T >()、const_pointer_cast< T >()和dynamic_pointer_cast< T >()
  • 支持operator< < 操作打印指针值,便与调试
  • 有工厂函数
template< class T, calss... Args >
shared_ptr< T> make_shared(Args && ... args);
  • 使用代码案例:
shared_ptr< string > sps(new string("smart"));
assert(sps->size() == 5);
shared_ptr< string> sp = make_shared< string > ("make_shared");
shared_ptr< vector< int >> spv = make_shared< vector< int >> (10,2);
assert(spv->size() == 10);
  • 应用于标准容器代码案例:
#include < boost/make_shared.hpp>
int main()
{
typedef vector< shared_ptr< int>> vs;
vs v(10);
int i=0;
for (vs::iterator pos = v.begin(); pos != v.end(); ++pos)
{
(*pos) = make_shared< int>(++i);
cout << *(*pos) << ",";
}
cout << endl;
shared_ptr < int > p = v[9];
*p = 100;
cout << *v[9] << endl;
}

shared_array

  • 通经常使用shared_ptr< std::vector>或者std::vector< shared_ptr>取代

weak_ptr(重点)

  • 未重载*和->。最大的作用是协助shared_ptr。观測资源使用情况
  • 代码演示样例:
int testWeakPtr()
{
boost::shared_ptr<int> sp(new int(10));
assert(sp.use_count() == 1); boost::weak_ptr<int> wp(sp);
assert(wp.use_count() == 1); if (!wp.expired())
{
boost::shared_ptr<int> sp2 = wp.lock();
*sp2 = 100;
assert(sp2.use_count() == 2);
assert(wp.use_count() == 2);
} assert(wp.use_count() == 1);
sp.reset();
assert(wp.expired());
assert(!wp.lock()); return 0;
}
  • 作用是打破循环引用,代码演示样例:
// 循环引用的情形
class node
{
public:
boost::shared_ptr<node> next;
~node()
{
cout << "delete node" << endl;
}
}; int testWeakPtrRecycleWrong()
{
auto n1 = boost::make_shared<node>();
auto n2 = boost::make_shared<node>(); n1->next = n2;
n2->next = n1; assert(n1.use_count() == 2);
assert(n2.use_count() == 2); return 0; // 循环引用,析构异常。程序退出时仍未析构
} // 避免循环引用的情形,主要就是node里的shared_ptr换成weak_ptr
class node1
{
public:
boost::weak_ptr<node1> next;
~node1()
{
cout << "delete node1" << endl;
}
}; int testWeakPtrRecycleRight()
{
auto n1 = boost::make_shared<node1>();
auto n2 = boost::make_shared<node1>(); n1->next = n2;
n2->next = n1; assert(n1.use_count() == 1);
assert(n2.use_count() == 1); if (!n1->next.expired())
{
// 调用lock()获得强引用,计数加1
auto n3 = n1->next.lock();
assert(n2.use_count() == 2);
}
assert(n2.use_count() == 1);
return 0;
}

intrusive_ptr(略)

pool(pool后缀的都是重点)

  • pool管理内存。仅仅能针对基础类型POD(Plain Old Data),由于不调用对象的构造函数。除非特殊情况。不须要自己释放
  • 调用演示样例代码:
int testPool()
{
pool<> pl(sizeof(int));
int *p = static_cast<int*>(pl.malloc()); // void*->int*
assert(pl.is_from(p)); pl.free(p);
for (int i = 0; i < 100;i++)
{
pl.ordered_malloc(10);
}
return 0;
}

object_pool

  • pool的子类。实现对类实例(对象)的内存池。会调用析构函数正确释放资源
  • 演示样例代码:
struct demo_class
{
public:
int a, b, c;
demo_class(int x = 1, int y = 2, int z = 3) : a(x), b(y), c(z) {}
~demo_class()
{
cout << "destruct" << endl;
}
}; int testObjPool()
{
object_pool<demo_class> pl;
demo_class *p = pl.malloc();
assert(pl.is_from(p)); // malloc 创建时内存并未初始化
assert(p->a!= 1 || p->b != 2 || p->c != 3); p = pl.construct(); // boost自带的construct仅仅能支持3个及以内的參数调用
p = pl.construct(7, 8, 9);
assert(p->a == 7); object_pool<string> pls;
for (int i = 0; i < 10; i++)
{
string *ps = pls.construct("hello object_pool");
cout << *ps << endl;
}
return 0;
}

析构会调用三次。malloc和两次construct均须要调用析构。是object_pool推断出了作用域自己主动调整的。

singleton_pool

  • 基础类型静态单件(包含基础指针类型)。提供线程安全
  • 演示样例代码
struct pool_tag{
int tag;
};
typedef singleton_pool<pool_tag, sizeof(pool_tag*)> spl;
int testSingletonPool()
{
pool_tag **p = (pool_tag **)spl::malloc();
assert(spl::is_from(p)); pool_tag ptag;
ptag.tag = 3;
*p = &ptag; cout << "testSingletonPool : " << (*p)->tag << endl;
spl::release_memory();
return 0;
}

pool_alloc

  • 提供对标准容器类型的内存分配器,当分配失败时能够抛异常。可是除非特别需求。应该使用stl自带的。假设要用pool_alloc需经过细致測试。保证与容器能够正常工作。

boost的内存管理的更多相关文章

  1. boost之内存管理

    内存管理一直是令C++程序员最头疼的工作,C++继承了C那高效而又灵活的指针,使用起来稍微不小心就会导致内存泄露.野指针.越界访问等访问.虽然C++标准提供了只能指针std::auto_ptr,但是并 ...

  2. (六)boost库之内存管理shared_ptr

    (六)boost库之内存管理shared_ptr 1.shared_ptr的基本用法 boost::shared_ptr<int> sp(new int(10)); //一个指向整数的sh ...

  3. Object-C内存管理的理解总结

    今天看到了OC的内存管理这块,觉得很亲切. 自己的习惯是尽量自己掌控程序的空间和时间,有点强迫症的感觉.用C和C++做项目的时候,时时刻刻都在操心这new和delete的配对使用和计数,学习stl和b ...

  4. [基础] C++与JAVA的内存管理

    在内存管理上(总之一句话——以后C++工程,一定要用智能指针!) 1.同是new一个对象,C++一定得手动delete掉,而且得时刻记住能delete的最早时间(避免使用空指针).JAVA可以存活于作 ...

  5. C++内存管理学习笔记(5)

    /****************************************************************/ /*            学习是合作和分享式的! /* Auth ...

  6. STL内存管理

    1. 概述 STL Allocator是STL的内存管理器,也是最低调的部分之一,你可能使用了3年stl,但却不知其为何物. STL标准如下介绍Allocator the STL includes s ...

  7. C++内存管理变革(6):通用型垃圾回收器 - ScopeAlloc

    本文已经迁移到:http://cpp.winxgui.com/cn:a-general-gc-allocator-scopealloc C++内存管理变革(6):通用型垃圾回收器 - ScopeAll ...

  8. C++中的垃圾回收和内存管理

    最开始的时候看到了许式伟的内存管理变革系列,看到性能测试结果的时候,觉得这个实现很不错,没有深入研究其实现.现在想把这个用到自己的一个项目中来,在linux下编译存在一些问题,所以打算深入研究一下. ...

  9. 【cocos2d-x 3.x 学习笔记】对象内存管理

    内存管理 内存管理一直是一个不易处理的问题.开发人员必须考虑分配回收的方式和时机,针对堆和栈做不同的优化处理,等等.内存管理的核心是动态分配的对象必须保证在使用完成后有效地释放内存,即管理对象的生命周 ...

随机推荐

  1. 【转载】form表单的两种提交方式,submit和button的用法

    1.当输入用户名和密码为空的时候,需要判断.这时候就用到了校验用户名和密码,这个需要在jsp的前端页面写:有两种方法,一种是用submit提交.一种是用button提交.方法一: 在jsp的前端页面的 ...

  2. 24. TABLES

    24. TABLES TABLES表提供有关数据库中表的信息. TABLES表有以下列: TABLE_CATALOG :表所属目录的名称.该值始终为def. TABLE_SCHEMA :表所属sche ...

  3. POJ 2631 Roads in the North (树的直径)

    题意: 给定一棵树, 求树的直径. 分析: 两种方法: 1.两次bfs, 第一次求出最远的点, 第二次求该点的最远距离就是直径. 2.同hdu2196的第一次dfs, 求出每个节点到子树的最长距离和次 ...

  4. Java线程和多线程(二)——对象中的wait,notify以及notifyAll方法

    Java对象中的wait,notify以及notifyAll方法 在Java的Object类中包含了3个final的方法,这三个方法允许线程来交流资源是否被锁定.这三个方法就是wait(),notif ...

  5. webservice学习第二天

    1 课程回顾 l 什么是webservice 远程调用技术:系统和系统之间的调用,获取远程系统里的业务数据 Webservice使用http传输SOAP协议的数据的一种远程调用技术 l Webserv ...

  6. Flask 架构 --xunfeng实例研究

    文件结构 │ Config.py # 配置文件 │ README.md # 说明文档 │ Run.bat # Windows启动服务 │ Run.py # webserver │ Run.sh # L ...

  7. oracle如何向空表中添加一个类型为clob的非空列

    一般的添加非空列的步骤是:先add可以为空的列,然后update该列为一个值(比如0),最后modify该列的类型 但是遇到类型为clob的就不行了.在modify这步时报错:ORA-22296:in ...

  8. 是时候学习真正的 spark 技术了

     
 spark sql 可以说是 spark 中的精华部分了,我感觉整体复杂度是 spark streaming 的 5 倍以上,现在 spark 官方主推 structed streaming, ...

  9. [POJ1984]Navigation Nightmare

    [POJ1984]Navigation Nightmare 试题描述 Farmer John's pastoral neighborhood has N farms (2 <= N <= ...

  10. 【尺取】HDU Problem Killer

    acm.hdu.edu.cn/showproblem.php?pid=5328 [题意] 给定一个长度为n的正整数序列,选出一个连续子序列,这个子序列是等差数列或者等比数列,问这样的连续子序列最长是多 ...