boost::shared_ptr是boost库中用来管理指针的模板,使用它需要#include <boost/shared_ptr.hpp>。本文介绍它的一些基本用法。

第一,boost::shared_ptr管理的指针所指向的对象必须在堆中,因为该模板会在对象离开作用域后调用delete方法,如果对象位于栈中,程序编译能通过,但在运行中会崩溃。另外改模板提供了swap方法,可以让两个模板指针相互交换所指向的对象。

 #include <vector>
#include <set>
#include <iostream>
#include <algorithm>
#include <boost/shared_ptr.hpp> // The application will produce a series of
// objects of type Foo which later must be
// accessed both by occurrence (std::vector)
// and by ordering relationship (std::set). struct Foo
{
Foo( int _x ) : x(_x) {}
~Foo() { std::cout << "Destructing a Foo with x=" << x << "\n"; }
int x;
/* ... */
}; typedef boost::shared_ptr<Foo> FooPtr; typedef struct FooPtrOps
{
bool operator()( const FooPtr & a, const FooPtr & b )
{ return a->x > b->x; }
void operator()( const FooPtr & a )
{ std::cout << a->x << "\n"; }
} foo_ptr_ops; foo_ptr_ops ins_foo_ptr_ops1 = foo_ptr_ops();
FooPtrOps *ins_foo_ptr_ops2 = new FooPtrOps();
FooPtrOps *ins_foo_ptr_ops3 = new foo_ptr_ops; int main()
{
{
std::vector<FooPtr> foo_vector;
std::set<FooPtr,FooPtrOps> foo_set; // NOT multiset! FooPtr foo_ptr( new Foo( ) );
foo_vector.push_back( foo_ptr );
foo_set.insert( foo_ptr ); foo_ptr.reset( new Foo( ) );
foo_vector.push_back( foo_ptr );
foo_set.insert( foo_ptr ); foo_ptr.reset( new Foo( ) );
foo_vector.push_back( foo_ptr );
foo_set.insert( foo_ptr ); foo_ptr.reset ( new Foo( ) );
foo_vector.push_back( foo_ptr );
foo_set.insert( foo_ptr ); std::cout << "foo_vector:\n";
std::for_each( foo_vector.begin(), foo_vector.end(), ins_foo_ptr_ops1 ); std::cout << "\nfoo_set:\n";
std::for_each( foo_set.begin(), foo_set.end(), *ins_foo_ptr_ops3 ); FooPtr foo_ptr1( new Foo( ) );
FooPtr foo_ptr2( new Foo( ) );
std::cout << "foo_ptr1: " << foo_ptr1->x << '\n';
std::cout << "foo_ptr2: " << foo_ptr2->x << '\n'; foo_ptr1.swap(foo_ptr2);
std::cout << "After swap:\n";
std::cout << "foo_ptr1: " << foo_ptr1->x << '\n';
std::cout << "foo_ptr2: " << foo_ptr2->x << '\n'; foo_ptr2.swap(foo_ptr1);
std::cout << "Swap again:\n";
std::cout << "foo_ptr1: " << foo_ptr1->x << '\n';
std::cout << "foo_ptr2: " << foo_ptr2->x << '\n'; int a = ;
int b[] = {, , , };
int *c = new int();
int *d = new int[]; /*
* Because variable a and b are on stack, while boost::shared_ptr will call delete method,
* the following two rows of code will cause error.
*/
// boost::shared_ptr<int> bsa(&a); // Error: Signal: SIGABRT (Aborted)
// boost::shared_ptr<int> bsb(b); // Error: Signal: SIGABRT (Aborted)
boost::shared_ptr<int> bsc(c);
boost::shared_ptr<int> bsd(d);
std::cout << "bsc: " << *bsc << " bsd: " << *bsd << std::endl; std::cout << "The variable field finished." << "\n";
} int *c = new int();
int *d = new int[];
boost::shared_ptr<int> bsc(c);
boost::shared_ptr<int> bsd(d);
std::cout << "bsc: " << *bsc << " bsd: " << *bsd << std::endl; std::cout << "\nProgram done.\n";
}

程序的运行结果:

foo_vector:

foo_set:

foo_ptr1:
foo_ptr2:
After swap:
foo_ptr1:
foo_ptr2:
Swap again:
foo_ptr1:
foo_ptr2:
bsc: bsd:
The variable field finished.
Destructing a Foo with x=
Destructing a Foo with x=
Destructing a Foo with x=
Destructing a Foo with x=
Destructing a Foo with x=
Destructing a Foo with x=
bsc: bsd: Program done.

 

第二,boost::shared_ptr支持隐藏类的定义。如下面的代码中,class implementation的定义可以放置于另一个源文件中,在利用boost::shared_ptr管理implementation类型的指针变量时,可以先声明一下类implementation,然后就能定义boost::shared_ptr< implementation >类型的指针变量。

 #include <boost/shared_ptr.hpp>
#include <iostream>
#include <algorithm> void print_val(int v)
{
std::cout << v << " ";
} class example
{
public:
example();
void do_something();
int val[];
class implementation;
boost::shared_ptr< implementation > _imp; // hide implementation details
}; class example::implementation
{
public:
~implementation() { std::cout << "destroying implementation\n"; }
}; example::example() : _imp( new implementation ) {} void example::do_something()
{
std::cout << "use_count() is " << _imp.use_count() << " ";
std::for_each(val, val + , print_val);
std::cout << "\n";
} int main()
{
example a;
a.val[] = ;
a.val[] = ;
a.val[] = ;
a.do_something();
example b(a);
b.do_something();
example c;
c = a;
a.do_something();
b.do_something();
c.do_something();
return ;
}

程序的运行结果:

use_count() is
use_count() is
destroying implementation
use_count() is
use_count() is
use_count() is
destroying implementation

第三,使用boost::shared_ptr提供的reset()方法,可以使boost::shared_ptr管理的指针所指向的对象的引用计数减一。当所指对象的引用计数减至0时,所指对象的析构函数将被调用,所指对象被销毁。

 #include <iostream>
#include <string>
#include <boost/shared_ptr.hpp> using namespace std; class Book
{
private:
string name_; public:
Book(string name) : name_(name)
{
cout << "Creating book " << name_ << " ..." << endl;
} ~Book()
{
cout << "Destroying book " << name_ << " ..." << endl;
}
}; int main()
{
cout << "=====Main Begin=====" << endl;
{
boost::shared_ptr<Book> myBook1(new Book("「1984」"));
cout << "myBook1: " << myBook1.use_count() << endl;
boost::shared_ptr<Book> myBook2(myBook1);
cout << "myBook1: " << myBook1.use_count() << endl;
boost::shared_ptr<Book> myBook3;
myBook3 = myBook1; cout << "\n****************************\n";
cout << "myBook1: " << myBook1.use_count() << endl;
cout << "myBook2: " << myBook2.use_count() << endl;
cout << "myBook3: " << myBook3.use_count() << endl; cout << "\n****************************\n";
myBook1.reset();
cout << "myBook1: " << myBook1.use_count() << endl;
cout << "myBook2: " << myBook2.use_count() << endl;
cout << "myBook3: " << myBook3.use_count() << endl; cout << "\n****************************\n";
myBook3.reset();
cout << "myBook1: " << myBook1.use_count() << endl;
cout << "myBook2: " << myBook2.use_count() << endl;
cout << "myBook3: " << myBook3.use_count() << endl; cout << "\n****************************\n";
myBook2.reset();
cout << "myBook1: " << myBook1.use_count() << endl;
cout << "myBook2: " << myBook2.use_count() << endl;
cout << "myBook3: " << myBook3.use_count() << endl; cout << "After reset ..." << endl;
}
cout << "===== Main End =====" << endl; return ;
}

程序的运行结果:

=====Main Begin=====
Creating book 「」 ...
myBook1:
myBook1: ****************************
myBook1:
myBook2:
myBook3: ****************************
myBook1:
myBook2:
myBook3: ****************************
myBook1:
myBook2:
myBook3: ****************************
Destroying book 「」 ...
myBook1:
myBook2:
myBook3:
After reset ...
===== Main End =====

boost::shared_ptr的更多相关文章

  1. [5] 智能指针boost::shared_ptr

    [1]boost::shared_ptr简介 boost::shared_ptr属于boost库,定义在namespace boost中,包含头文件#include<boost/shared_p ...

  2. 记录以下boost::shared_ptr的一个使用细节

    shared_ptr<T>::operator->返回的是T*类型指针,非const T*指针.因此通过const shared_ptr<T>&类型的ptr可以直 ...

  3. 关于智能指针boost::shared_ptr

    boost库中的智能指针shared_ptr, 功能强大, 且开销小,故受到广大coder的欢迎. 但在实际的使用过程中,笔者也发现了一些不足. 1.定制的删除器 shared_ptr除了可以使用默认 ...

  4. #include <boost/shared_ptr.hpp>

    共享指针 这个智能指针命名为boost::shared_ptr,定义在boost/shared_ptr.hpp里.智能指针boost::shared_ptr基本上类似于boost::scoped_pt ...

  5. 智能指针剖析(下)boost::shared_ptr&其他

    1. boost::shared_ptr 前面我已经讲解了两个比较简单的智能指针,它们都有各自的优缺点.由于 boost::scoped_ptr 独享所有权,当我们真真需要复制智能指针时,需求便满足不 ...

  6. C++智能指针剖析(下)boost::shared_ptr&其他

    1. boost::shared_ptr 前面我已经讲解了两个比较简单的智能指针,它们都有各自的优缺点.由于 boost::scoped_ptr 独享所有权,当我们真真需要复制智能指针时,需求便满足不 ...

  7. 【C++】boost::shared_ptr boost::make_shared

    一.shared_ptr shared_ptr作为一个动态分配的对象,当最后一个指向其内容的指针销毁(destroyed)或重置(reset),其指向的内容会被销毁(deleted).不再需要显式调用 ...

  8. 智能指针tr1::shared_ptr、boost::shared_ptr使用

    对于tr1::shared_ptr在安装vs同一时候会自带安装,可是版本号较低的不存在.而boost作为tr1的实现品,包括 "Algorithms Broken Compiler Work ...

  9. boost shared_ptr weak_ptr

    文档: http://www.boost.org/doc/libs/1_57_0/libs/smart_ptr/shared_ptr.htm shared_ptr构造有个原型 template< ...

随机推荐

  1. Django day25 序列化组件(*****)

    序列化:将变量从内存中存储或传输的过程称之为序列化 1.序列化组件是干什么用的? 对应着表,写序列化的类 2.如何使用序列化组件 Serializer 1) 重命名:用source:xx = seri ...

  2. GoLang 编译exe添加ICO图标

    我们在做Go开发的时候在Window平台下编译出来的exe后大部分都是没有图标,看起来很难看.下面我们说下如何添加一个图标. 1.首先在根目录下,exe的同级目录下创建.rc文件, IDI_ICON1 ...

  3. DB2锁表或超时解决方案

    DB2锁表或超时 一.场景 对数据表进行更新(查询没问题),错误提示如下: SQLCODE=-911, SQLSTATE=40001, DRIVER=3.63.75SQL0911N The curre ...

  4. php微信开放平台--第三方网页微信扫码登录(OAuth2.0)

    第一.OAuth2.0 OAuth(开放授权)是一个开放标准,允许用户让第三方应用访问该用户在某一网站上存储的私密的资源(如照片,视频,联系人列表),而无需将用户名和密码提供给第三方应用. 允许用户提 ...

  5. ASP.NET MVC5 之 AspNetUsers 表增加字段

    MVC5 执行数据库迁移时,会生成一些默认的数据表,但是在实际的工作中.若用到的时候,难免要增添一些字段. 1.AspNetUsers 增加字段 A.打开MVC中的 IdentityModels.cs ...

  6. MySQL索引----数据结构及算法原理

    摘要 本文以MySQL数据库为研究对象,讨论与数据库索引相关的一些话题.特别需要说明的是,MySQL支持诸多存储引擎,而各种存储引擎对索引的支持也各不相同,因此MySQL数据库支持多种索引类型,如BT ...

  7. C# windform自定义控件的属性小知识

    word中的加粗变斜之类的一直让我以为是button,直到我接触了自定义控件,才发现实现这种机能最好的是CheckBox,然后我们在做一个系统的时候,这种控件有可能要用好多次,总不能在用一次的时候,就 ...

  8. java与javascript之间json格式数据互转

    javascript中对象与字符串的互转 对象转为字符串:通过JSON.encode方法,这个是json.js里面的方法,引入到当前文件就可以了. 字符串转换为对象:①使用JSON.decode方法, ...

  9. 我的liunx开发环境的配置之路

    相信有不少人和我一样,虽然是做纯linux开发,但并不排斥windows,并且喜欢在windows下面的使用各种好用的工具来让linux的编程工作变得更加方便.实际上每一个系统都有他的过人支持,win ...

  10. 怎样用Fiddler模拟网络超时

    转自:http://materliu.github.io/all/web/2014/04/28/fiddler-timeout.html   用fiddler模拟网络请求超时 用fiddler模拟网络 ...