Boost库中shared_ptr(上)

1、共享性智能指针(shared_ptr)

引用计数型指针

shared_ptr是一个最像指针的“智能指针”,是boost.smart_ptr库中最有价值,最重要,也是最有用的。

 shared_ptr实现的是引用技术型的智能指针,可以被拷贝和赋值,在任意地方共享它,当没有代码使用(此时引用

        计数为0)它才删除被动态分配的对象。shared_ptr也可以被安全的放到标准容器中;

2、怎么使用shared_ptr

举一个操作的例子:

#include<iostream>
#include<boost/smart_ptr.hpp>
using namespace std;
using namespace boost;

int main(void){
    int *p = new int(10);
    shared_ptr<int> ps(p);
//    cout<<*ps<<endl;

    cout<<ps.unique()<<endl; //判断对空间是否唯一,
    cout<<ps.use_count()<<endl;
    shared_ptr<int> ps1 = ps;
    cout<<ps.unique()<<endl; //此时有两个对空间有共享,所以不唯一,是0
    cout<<ps.use_count()<<endl;
    shared_ptr<int> ps2;
    ps2 = ps1;
    cout<<ps.use_count()<<endl;
}

关键在shared_ptr中存在共享引用计数。

3、框架的搭建

阅读源代码:

shared_ptr 中的私有数据成员:

private:
    T *px;
    shared_count pn; //对象成员,肯定先调这个对象的构造函数;

之前的引用计数通过一个指针,现在的引用计数通过一个对象,pn

构造函数的调用顺序:先虚基类,父类,对象成员,最后构造自己;

此时的模型如下:


其后调用对象成员的构造函数

shared_counted中的私有数据成员:

private:
    sp_counted_base *pi; //有一个指向引用计数器父类的指针;

此时就得先写:sp_counted_base类了;

sp_counted_base类中的私有数据成员:

private:
    long use_count_;

然后看到在shared_counted的构造函数:

public:
    template<class T>  //此时类型不定,写模板函数
        shared_count(T *p) : pi(new sp_counted_impl_xx(p)){ //特别重要,这个构造函数

此时就得写sp_counted_impl_xx类了:这是继承sp_counted_base类

其内部数据时成员:

private:
    T *px_;

此时整体的建构体系就已经形成:

我认为是这样的:(1)、先实现了shared_ptr类,因为有对象成员,其后调用构造函数,

(2)、实现了shared_count; 其数据成员有sp_counted_base,

(3)、因为编译器的顺序,先类名,在数据成员,最后函数,所以此时先实现sp_counted_base;

(4)、因为shared_counted中的构造函数要在堆上开辟sp_counted_impl_xx空间,最后实现是sp_counted_impl_xx

它有继承sp_counted_base,所以构造函数的调用顺序就很清楚了。

构造函数的调用顺序:sp_counted_base、sp_counted_impl_xx、shared_count、shared_ptr

此时的具体实现代码如下:

#ifndef _CONFIG_H_
#define _CONFIG_H_

#include<iostream>
using namespace std;

#endif
////////////////////////////////////////////////////////////////////////////
#ifndef _SHARED_PTR_H_
#define _SHARED_PTR_H_

#include"shared_count.h"

template<class T>
class shared_ptr{
public:
    shared_ptr(T *p = 0) : px(p), pn(p){
        cout<<"Create shared_ptr object!"<<endl;
    }
    ~shared_ptr(){
        cout<<"Free shared_ptr object"<<endl;
    }
private:
    T *px;
    shared_count pn;
};

#endif
///////////////////////////////////////////////////////////////////////////////
#ifndef _SHARED_COUNT_H_
#define _SHARED_COUNT_H_

#include"config.h"
#include"sp_counted_base.h"
#include"sp_counted_impl_xx.h"

class shared_count{
public:
    template<class T>  //此时类型不定,写模板函数
        shared_count(T *p) : pi(new sp_counted_impl_xx<T>(p)){
        cout<<"Create shared_cout object!"<<endl;
    }
    ~shared_count(){
        cout<<"Free shared_count object"<<endl;
    }
private:
    sp_counted_base *pi;
};

#endif
///////////////////////////////////////////////////////////////////////////////
#ifndef SP_COUNTED_BASE_H_
#define SP_COUNTED_BASE_H_

#include"config.h"

class sp_counted_base{
public:
    sp_counted_base() : use_count_(1){
        cout<<"Create sp_counted_base object"<<endl;
    }
    ~sp_counted_base(){
        cout<<"Free sp_counted_base object"<<endl;
    }
private:
    long use_count_;
};

#endif
//////////////////////////////////////////////////////////////////////////////////////
#ifndef SP_COUNTED_IMPL_XX_H_
#define SP_COUNTED_IMPL_XX_H_

#include"sp_counted_base.h"

template<class T>
class sp_counted_impl_xx : public sp_counted_base{
public:
    sp_counted_impl_xx(T *p) : px_(p){
        cout<<"Create sp_counted_impl_xx object"<<endl;
    }
    ~sp_counted_impl_xx(){
        cout<<"Free sp_counted_impl_xx object"<<endl;
    }
private:
    T *px_;
};

#endif
//////////////////////////////////////////////////////////////////////////////////////////////
#include<iostream>
#include"shared_ptr.h"
using namespace std;

int main(void){
    int *p = new int(10);
    shared_ptr<int> ps(p);   
}

以下是运行结果:

以上就是只搭好了大致的框架,并没有考虑内存泄漏,析构的具体写法和其它函数的实现;

那么整个模型如下:

时间: 2024-08-07 00:16:05

Boost库中shared_ptr(上)的相关文章

模拟实现c++标准库和boost库中的智能指针

我们知道c++标准库中定义了智能指针auto_ptr,但是我们很少用它,因为虽然它能够自动回收动态开辟的内存,不需要程序员自己去维护动态开辟的内存,但是当用它去赋值或者是拷贝构造时有一个管理权转移的过程,这样我们就不能很方便的使用auto_ptr. 下面是简单的auto_ptr的实现,我们可以看到在复制和赋值时它将转移管理权. template<class T> class AutoPtr { public:      AutoPtr(T* ptr)       :_ptr(ptr)     

BOOST 库中filesyatem 库的学习

/*FileSyatem 库的学习 ------------------------------------------------------------------------------------------------------------库的使用方式 嵌入源码的形式: #define BOOST_SYSTEN_NO_LIB #define BOOST_FILESYSTEM_NO_LIB #include<boost\filesystem.hpp> ----------------

boost库中的 program_options

1.阅读rviz中的源码时在rviz/visualizer_app.cpp中遇到如下代码: po::options_description options; options.add_options() ("help,h", "Produce this help message") ("splash-screen,s", po::value<std::string>(), "A custom splash-screen ima

Boost库中scoped_ptr

1.VC和VS VC版并不是标准C++,VS版符合标准C++,其语法相当严格. 缺点:VC和VS都只能释放一个具体类型空间,不能对数组空间进行释放,还有写时拷贝的问题:         所以引发了Boost库的出现来解决此类问题. 2.Boost库 推荐看一下Boost库完全开发指南. Boost本身是开源库,在C++中的地位举足轻重,第三章内存管理,智能指针: C++中也提供了智能指针,但是并不能解决所有问题. smart_ptr库中:new delete的运用不正确,是C++中造成资源获取/

详解boost库中的Message Queue .

Message Queue(后文简写成MQ或消息队列)是boost库中用来封装进程间通信的一种实现,同一台机器上的进程或线程可以通过消息队列来进行通迅.消息队列中的消息由优先级.消息长度.消息数据三部分组成.这里需要注意的事,MQ只是简单的将要发送的数据在内存中进行拷贝,所以我们在发送复杂结构或对象时,我们需要将其序列化后再发送,接收端接收时要反序列化,也就是说我们要自己去定义区分一条消息(就是自定义网络通迅协议).在MQ中,我们可以使用三模式去发送和接收消息: 阻塞:在发送消息时,若消息队列满

Boost库中的智能指针 shared_ptr智能指针

shared_ptr智能指针的意思即:boost::shared_ptr是可以智能的管理动态分配的内存资源,几个智能指针可以同时共享一个动态分配的内存的所有权. 下面我们通过一个例子来学习一下它的用法: 注 :使用shared_ptr智能指针,要加入#include <boost/shared_ptr.hpp>头文件 class example { public: ~example() { std::cout <<"It's over\n"; } void do

boost库中thread多线程详解2——mutex与lock

1. mutex对象类 mutex类主要有两种:独占式与共享式的互斥量.▲ 独占式互斥量:mutex: 独占式的互斥量,是最简单最常用的一种互斥量类型try_mutex: 它是mutex的同义词,为了与兼容以前的版本而提供timed_mutex: 它也是独占式的互斥量,但提供超时锁定功能▲ 递归式互斥量:recursive_mutex: 递归式互斥量,可以多次锁定,相应地也要多次解锁recursive_try_mutex: 它是recursive_mutex 的同义词,为了与兼容以前的版本而提供

自己实现的Boost库中的lexical_cast随意类型转换

知道了C++的I/O设施之后.这些就变的非常easy了. 假设你常常使用,时间长了就会有感觉.这个事情是多此一举吗?就当是练习吧,知道原理之后,你会认为用起来更舒畅,更喜欢C++了. #include <iostream> #include <vector> #include <string> #include <sstream> #include <algorithm> #include <iterator> using names

自己实现的Boost库中的lexical_cast任意类型转换

知道了C++的I/O设施之后,这些就变的很简单了.如果你经常使用,时间长了就会有感觉.这个事情是多此一举吗?就当是练习吧,知道原理之后,你会觉得用起来更舒畅,更喜欢C++了. #include <iostream> #include <vector> #include <string> #include <sstream> #include <algorithm> #include <iterator> using namespace