[5] 智能指针boost::shared_ptr
【1】boost::shared_ptr简介
boost::shared_ptr属于boost库,定义在namespace boost中,包含头文件#include<boost/shared_ptr.hpp>便可以使用。
上篇《智能指针boost::scoped_ptr》中我们看到boost::scoped_ptr独享所有权,不允许赋值、拷贝。
而boost::shared_ptr是专门用于共享所有权的,由于要共享所有权,其在内部使用了引用计数机制。同时也就意味着支持赋值和拷贝。
boost::shared_ptr也是用于管理单个堆内存对象的。
【2】boost::shared_ptr详解
应用实例代码如下:
#include <iostream>
#include <boost/shared_ptr.hpp> class Int
{
public:
Int(int nValue = )
{
m_nValue = nValue;
std::cout << "Constructor: " << m_nValue << std::endl;
}
~Int()
{
std::cout << "Destructor: " << m_nValue << std::endl;
}
void PrintValue()
{
std::cout << "PrintValue: " <<m_nValue<< std::endl;
}
void SetValue(int nSetValue)
{
m_nValue = nSetValue;
} private:
int m_nValue;
}; void TestShared_Ptr(boost::shared_ptr<Int> spInt)
{ // 注意:无需使用 reference (或 const reference)
spInt->PrintValue();
std::cout << "TestShared_Ptr UseCount: " << spInt.use_count() << std::endl;
} void TestShared_Ptr2()
{
boost::shared_ptr<Int> spInt(new Int());
if (spInt.get())
{
spInt->PrintValue();
spInt.get()->SetValue();
spInt->PrintValue();
(*spInt).SetValue();
spInt->PrintValue();
} std::cout << "TestShared_Ptr2 UseCount: " << spInt.use_count() << std::endl;
TestShared_Ptr(spInt);
std::cout << "TestShared_Ptr2 UseCount: " << spInt.use_count() << std::endl; //spInt.release();// 编译 error: 同样,shared_ptr也没有release函数
} //执行结果如下:
/*
Constructor: 10
PrintValue: 10
PrintValue: 20
PrintValue: 30
TestShared_Ptr2 UseCount: 1
PrintValue: 30
TestShared_Ptr UseCount: 2
TestShared_Ptr2 UseCount: 1
Destructor: 30
*/
实例可见,boost::shared_ptr也可以很方便的使用。并且没有release()函数。
关键的一点,boost::shared_ptr内部维护了一个引用计数,由此可以支持复制、参数传递等。
boost::shared_ptr提供了一个函数use_count(),此函数返回 boost::shared_ptr内部的引用计数。
查看执行结果,我们可以看到在 TestShared_Ptr2函数中,引用计数为1,传递参数后(此处进行了一次复制),
在函数TestShared_Ptr内部,引用计数为2,在TestShared_Ptr返回后,引用计数又降低为1。
另外,由TestShared_Ptr2内创建智能指针对象,到函数结束再析构智能指针对象,确保释放掉内存资源。
当我们需要使用一个共享对象的时候,boost::shared_ptr是最佳选择。
此例也正体现了boost::shared_ptr是支持值语义,提供引用计数机制及RAII支持的智能指针。
【3】boost::shared_ptr总结
boost::shared_ptr的管理机制其实并不复杂,就是对所管理的对象进行了引用计数。
当新增一个boost::shared_ptr对该对象进行管理时,就将该对象的引用计数加一;
减少一个boost::shared_ptr对该对象进行管理时,就将该对象的引用计数减一;
如果该对象的引用计数为0的时候,说明没有任何指针对其管理,才调用delete释放其所占的内存。
boost::shared_ptr并不是绝对安全,下面几条规则能使我们更加安全的使用boost::shared_ptr:
1.避免对shared_ptr所管理的对象的直接内存管理操作,以免造成该对象的重释放
2.shared_ptr并不能对循环引用的对象内存自动管理(这点是其它各种引用计数管理内存方式的通病)。
3.不要构造一个临时的shared_ptr作为函数的参数。
如下列代码则可能导致内存泄漏:
void test()
{
fun(boost::shared_ptr<Int>(new Int()).g());
}
//正确的用法为:
void test()
{
boost::shared_ptr<Int> spInt(new Int());
fun(spInt.g());
}
当函数g()抛异常的时候就会泄露了,这个是boost文档上特地注明的标准bad Practices。
Good Good Study, Day Day Up.
顺序 选择 循环 总结
[5] 智能指针boost::shared_ptr的更多相关文章
- 关于智能指针boost::shared_ptr
boost库中的智能指针shared_ptr, 功能强大, 且开销小,故受到广大coder的欢迎. 但在实际的使用过程中,笔者也发现了一些不足. 1.定制的删除器 shared_ptr除了可以使用默认 ...
- [6] 智能指针boost::weak_ptr
[1]boost::weak_ptr简介 boost::weak_ptr属于boost库,定义在namespace boost中,包含头文件 #include<boost/weak_ptr.hp ...
- C++ 智能指针 boost::scoped_ptr分析
1.scoped_ptr的实现原理及特性 特性:scoped_ptr和auto_ptr类似,但最大的区别就是不能转让管理权限,也就是说scoped_ptr禁止用户进行拷贝和赋值 实现原理:如何才能禁止 ...
- 【C++11新特性】 C++11智能指针之shared_ptr
C++中的智能指针首先出现在“准”标准库boost中.随着使用的人越来越多,为了让开发人员更方便.更安全的使用动态内存,C++11也引入了智能指针来管理动态对象.在新标准中,主要提供了shared_p ...
- C++ | 再探智能指针(shared_ptr 与 weak_ptr)
上篇博客我们模拟实现了 auto_ptr 智能指针,可我们说 auto_ptr 是一种有缺陷的智能指针,并且在C++11中就已经被摈弃掉了.那么本章我们就来探索 boost库和C++11中的智能指针以 ...
- 智能指针之shared_ptr基本概述
1.shared_ptr允许有多个指针指向同一个对象,unique_ptr独占所指向的对象. 2.类似于vector,智能指针也是模板.创建智能指针: shared_ptr<string> ...
- C++智能指针之shared_ptr与右值引用(详细)
1. 介绍 在 C++ 中没有垃圾回收机制,必须自己释放分配的内存,否则就会造成内存泄露.解决这个问题最有效的方法是使用智能指针(smart pointer).智能指针是存储指向动态分配(堆)对象指针 ...
- 智能指针tr1::shared_ptr、boost::shared_ptr使用
对于tr1::shared_ptr在安装vs同一时候会自带安装,可是版本号较低的不存在.而boost作为tr1的实现品,包括 "Algorithms Broken Compiler Work ...
- 【STL学习】智能指针之shared_ptr
前面已经学习过auto_ptr,这里补充另外一种智能指针,比auto_ptr要更强力更通用的shared_ptr. shared_ptr 简介及使用选择 几乎所有的程序都需要某种形式的引用计数智能指 ...
随机推荐
- 基于zepto的插件之移动端无缝向上滚动并上下触摸滑动
该插件乃本博客作者所写,目的在于提升作者的js能力,也给一些js菜鸟在使用插件时提供一些便利,老鸟就悠然地飞过吧. 公司的移动端项目是基于zepto的,有一个页面要求文字能够无缝地不停向上滚动,但查了 ...
- mysql 的2个关于事务和安全性的参数
innodb_flush_log_at_trx_commit:(mysql写事物日志的方式) 0 log buffer 会每秒写入到日志文件中,并刷新到磁盘 (提交方式与事物无关,性能最好) 1 事 ...
- js动态获取当前系统时间+js字符串转换为date日期对象
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...
- $_POST 变量以及$GLOBALS['HTTP_RAW_POST_DATA']
$_POST 变量是一个数组,内容是由 HTTP POST 方法发送的变量名称和值. $_POST 变量用于收集来自 method="post" 的表单中的值.从带有 POST 方 ...
- CentOs5.8下安装Oracle12C
12C安装向导: http://docs.oracle.com/database/121/LTDQI/toc.htm 12C下载地址: http://www.oracle.com/technetwor ...
- 【7集iCore3基础视频】7-5 iTool2驱动安装
iTool2驱动安装: 高清源视频:链接:http://pan.baidu.com/s/1dF5FtlB%20密码:g5x7 iCore3 购买链接:https://item.taobao.com/i ...
- (一)jvm
jvm,作为java平台通用性的实现基础,重要性不言而喻. 1.开发新项目,写运行脚本时要运用相关知识,确定jvm参数 2.维护老项目,需要对jvm进行性能调优 jvm内存划分: 1.程序计数器 2. ...
- Android WebApp开发使用Genymotion连接Fiddler2/Charles代理调试
1. 目的 在模拟器的浏览器或app hybrid开发中遇到chrome调试代码为线上代码或者混淆代码时,可以利用fiddler/charles为genymotion配置代理, 可以方便的 ...
- javaWeb中servlet开发(3)——Servlet生命周期
生命周期:是一个程序的存在周期,servlet由于是受容器的管理,所以容器来决定其生命周期 1.servlet生命周期 2.servlet生命周期对应的方法 3.servlet生命周期代码 publi ...
- git pull时出现unable to unlink old 一个不该犯下的错误
在日常开发中,当团队内有人将新的代码打成jar文件提交,并且未改名的时候,可能会出现这样的错误"error: unable to unlink old 'Test/lib/xxx-1.0.0 ...