shared_ptr和intrusive_ptr的对比差别 RAW POINTER
来源:互联网 发布:java是解释型语言吗 编辑:程序博客网 时间:2024/06/06 12:53
boost::intrusive_ptr一种“侵入式”的引用计数指针,它实际并不提供引用计数功能,而是要求被存储的对象自己实现引用计数功能,并提供intrusive_ptr_add_ref和intrusive_ptr_release函数接口供boost::intrusive_ptr调用。
下面通过一个具体的例子来说明boost::intrusive_ptr的用法,首先实现一个基类intrusive_ptr_base,定义intrusive_ptr_add_ref和intrusive_ptr_release函数来提供引用计数功能。
/**
* intrusive_ptr_base基类,提供intrusive_ptr_add_ref()和intrusive_ptr_release()函数来提供引用计数功能;
* 使用boost::intrusive_ptr指针存储的用户类类型必须继承自intrusive_ptr_base基类。
*/
#include <ostream>
#include <boost/checked_delete.hpp>
#include <boost/detail/atomic_count.hpp>
template
<
class
T>
class
intrusive_ptr_base {
public
:
/**
* 缺省构造函数
*/
intrusive_ptr_base(): ref_count(0) {
std::cout <<
" Default constructor "
<< std::endl;
}
/**
* 不允许拷贝构造,只能使用intrusive_ptr来构造另一个intrusive_ptr
*/
intrusive_ptr_base(intrusive_ptr_base<T>
const
&): ref_count(0) {
std::cout <<
" Copy constructor..."
<< std::endl;
}
/**
* 不允许进行赋值操作
*/
intrusive_ptr_base& operator=(intrusive_ptr_base
const
& rhs) {
std::cout <<
" Assignment operator..."
<< std::endl;
return
*
this
;
}
/**
* 递增引用计数(放到基类中以便compiler能找到,否则需要放到boost名字空间中)
*/
friend
void
intrusive_ptr_add_ref(intrusive_ptr_base<T>
const
* s) {
std::cout <<
" intrusive_ptr_add_ref..."
<< std::endl;
assert
(s->ref_count >= 0);
assert
(s != 0);
++s->ref_count;
}
/**
* 递减引用计数
*/
friend
void
intrusive_ptr_release(intrusive_ptr_base<T>
const
* s) {
std::cout <<
" intrusive_ptr_release..."
<< std::endl;
assert
(s->ref_count > 0);
assert
(s != 0);
if
(--s->ref_count == 0)
boost::checked_delete(
static_cast
<T
const
*>(s));
//s的实际类型就是T,intrusive_ptr_base<T>为基类
}
/**
* 类似于shared_from_this()函数
*/
boost::intrusive_ptr<T> self() {
return
boost::intrusive_ptr<T>((T*)
this
);
}
boost::intrusive_ptr<
const
T> self()
const
{
return
boost::intrusive_ptr<
const
T>((T
const
*)
this
);
}
int
refcount()
const
{
return
ref_count;
}
private
:
///should be modifiable even from const intrusive_ptr objects
mutable
boost::detail::atomic_count ref_count;
};
用户类类型需要继承intrusive_ptr_base基类,以便具有引用计数功能。
#include <iostream>
#include <string>
#include <boost/intrusive_ptr.hpp>
#include "intrusive_ptr_base.hpp"
/**
* 用户类类型继承自intrusive_ptr_base,该实现方式类似于boost::enable_shared_from_this<Y>
*/
class
Connection :
public
intrusive_ptr_base< Connection > {
public
:
/**
* 构造函数,调用intrusive_ptr_base< Connection >的缺省构造函数来初始化对象的基类部分
*/
Connection(
int
id, std::string tag):
connection_id( id ), connection_tag( tag ) {}
/**
* 拷贝构造函数,只复制自身数据,不能复制引用计数部分
*/
Connection(
const
Connection& rhs):
connection_id( rhs.connection_id ), connection_tag( rhs.connection_tag) {}
/**
* 赋值操作,同样不能复制引用计数部分
*/
const
Connection operator=(
const
Connection& rhs) {
if
(
this
!= &rhs) {
connection_id = rhs.connection_id;
connection_tag = rhs.connection_tag;
}
return
*
this
;
}
private
:
int
connection_id;
std::string connection_tag;
};
int
main() {
std::cout <<
"Create an intrusive ptr"
<< std::endl;
boost::intrusive_ptr< Connection > con0 (
new
Connection(4,
"sss"
) );
//调用intrusive_ptr_add_ref()递增引用计数
std::cout <<
"Create an intrusive ptr. Refcount = "
<< con0->refcount() << std::endl;
boost::intrusive_ptr< Connection > con1 (con0);
//调用intrusive_ptr_add_ref()
std::cout <<
"Create an intrusive ptr. Refcount = "
<< con1->refcount() << std::endl;
boost::intrusive_ptr< Connection > con2 = con0;
//调用intrusive_ptr_add_ref()
std::cout <<
"Create an intrusive ptr. Refcount = "
<< con2->refcount() << std::endl;
std::cout <<
"Destroy an intrusive ptr"
<< std::endl;
return
0;
}
程序运行输出:
Create an intrusive ptr
Default constructor
intrusive_ptr_add_ref...
Create an intrusive ptr. Refcount = 1
intrusive_ptr_add_ref...
Create an intrusive ptr. Refcount = 2
intrusive_ptr_add_ref...
Create an intrusive ptr. Refcount = 3
Destroy an intrusive ptr
intrusive_ptr_release...
intrusive_ptr_release...
intrusive_ptr_release...
对比boost::shared_ptr
使用boost::shared_ptr用户类本省不需要具有引用计数功能,而是由boost::shared_ptr来提供;使用boost::shared_ptr的一大陷阱就是用一个raw pointer多次创建boost::shared_ptr,这将导致该raw pointer被多次销毁当boost::shared_ptr析构时。即不能如下使用:
那么为什么通常鼓励大家使用shared_ptr,而不是intrusive_ptr呢, 在于shared_ptr不是侵入性的,可以指向任意类型的对象; 而intrusive_ptr所要指向的对象,需要继承intrusive_ptr_base,即使不需要,引用计数成员也会被创建。
- shared_ptr和intrusive_ptr的对比差别 RAW POINTER
- shared_ptr的错误free(): invalid pointer
- intrusive_ptr
- intrusive_ptr
- Boost智能指针——scoped_ptr、shared_ptr、weak_ptr、intrusive_ptr
- premiere和EDIUS对比差别有多少
- c++ smart pointer之shared_ptr
- rust raw pointer使用方法(1)
- rust raw pointer使用方法(2)
- rust raw pointer使用方法(3)
- rust raw pointer使用方法(4)
- make_shared和shared_ptr的区别
- shared_ptr的理解和注意事项
- shared_ptr的使用和陷阱
- shared_ptr的使用和陷阱
- c++ shared_ptr误区之row pointer被多组shared_ptr拥有
- C++ - "shared_ptr" 拆分智能指针(smart pointer)
- boost智能指针之shared_ptr,scoped_ptr,intrusive_ptr,weak_ptr源码简析
- 远程获取文件大小
- 设计和程序中必须做的事情!!!
- 学习总结20150915--背景颜色
- Ubuntu Server Install Mysql 5.6
- Eclipse 开发 Android 卡死
- shared_ptr和intrusive_ptr的对比差别 RAW POINTER
- android studio 修改项目CVS账号工具修改不成功,手动修改文件太多
- Ubuntu常用命令
- uva 10474
- .NET基础--break与continue区别
- poj2456-Aggressive cows(nyoj586)【贪心-二分】
- 学习网站收集
- 图片剪裁
- AsyncTask的用法