c++智能指针,从源码开始认识

智能指针(smart pointer)是c++群体中热门的议题,围绕它有很多有价值的讨论和结论。它实践了推荐书目【1】中的代理模式,代理了原始的“裸”指针的行为,为它添加了更多更有用的特性;

如果没有智能指针,程序员必须保证new 对象能在争取的时机delete,四处编写异常捕获代码以释放资源,而智能指针则可以在推出作用域的时候---不管是正常流程离开还是因为异常离开---总调用delete来析构在堆上动态分配的对象。

在这学习的几天中,我将我这三天由浅到深对c++智能指针的学习 记录总结下来。

存在很多种智能指针,其中最有名的的应该就是c++ 98标准中的“自动指针" std::auto_ptr,它不分的解决了获取资源自动释放的问题;

智能指针,并不是指针,而是类调用对象指针,

《memory》1-->AUTO_PTR :

auto_ptr 的构造函数接受new 操作符或者对象工厂创建出的对象指针作为参数:

int *p = new int[10];

auto_ptr<int> pa(p);

由上述代码,从而代理了原始代码:因为重载了 operator *和operator ->,

其行为非常类似指针,可以把它用在大多数普通指针可用的地方。

c++语言会保证auto_ptr 对象销毁,调用auto_ptr的析构函数,进而使用delete操作符删除原始指针释放资源。

ps:当类的拷贝构造函数是浅拷贝时,不用delete,巧妙的利用临时指针会自动释放的原理将空间释放掉

auto_ptr 很好用,被包含在c++标准库令它在世界范围内被广泛使用,使 智能指针的思想,用法,深入人心。但标准库函数没有覆盖智能指针的全部领域,尤其是最重要的引用计数型智能指针。

 

 

 

《bosst.smart_ptr》2.scoped_ptr:

boost.smart_ptr库是对c++98标准的一个绝佳补充。他提供了六种智能指针,包括scoped_ptr,socped_array,shared_ptr,shared_array,weak_ptr和instrusive_ptr;

 

 

上述这些智能指针都位于名字空间boost,为了使用smart_ptr组件,需要包含头文件<boost/smart_ptr.hpp> using namespace boost;

scoped_ptr 是一个很类似auto_ptr的智能指针,它包装了new 操作符在堆上分配的动态对象,能够保证动态创建的对象在任何时候都可以被正确的删除。但scoped_ptr的所有权更加严格,不能转让,一旦scoped_ptr获取了对象的管理权,你就无法再从它那里取回来。并且scoped_ptr不支持比较

scoped_ptr的类摘要如下:

template<typename T>
class scoped_ptr
{
scoped_ptr(const scoped_ptr<T> &);
scoped_ptr<T>& operator=(const scoped_ptr<T> &);
void operator==( scoped_ptr const& ) const;
    void operator!=( scoped_ptr const& ) const;
public:
explicit scoped_ptr(T *p = 0) : px(p)
{}

 

因为scoped_ptr类的构造函数和赋值函数 都被定义在了私有成员里,所以一旦scoped_ptr获取了对象的管理权,你就无法再从他那里收回来。

scoped_ptr的构造函数接受一个类型为T*的指针p,创建出一个soped_ptr对象,并在内部保存指针参数p,P必须是一个new 表达式动态分配的结果,或者是个空指针,当scoped_ptr对象的生命期结束时,析构函数~scoped_ptr()会使用delete操作符自动销毁索堡村的指针对象,从而正确的回收资源。

reset()功能是重置scoped_ptr,它删除原来保存的指针,在保存新的指针值p,如果p,是空指针,那么scoped_ptr,将不再持有任何指针,一般情况下reset()不应该被调用,因为他违背了scoped_ptr的本意,  资源应该一直由scoped_ptr自己自动管理。

使用的时候不需要我们再去delete;

 

 

<boost.smart.ptr>3.shared_ptr

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

shared_ptr与scoped_ptr一样包装了new操作符在堆上分配的动态对象,但它实现的引用计数型的智能指针,可以被自由的拷贝和赋值,在任意的地方共享它,当没有代码使用它时(引用计数为0)才删除被包装的动态分配的对象,shared_ptr也可以安全的放到标准容器中,并弥补了auto_ptr因为转移语义而不能把指针作为STL容器元素的缺陷。

 

 

主函数和头文件简单功能性整理如下:

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


#include"shared_ptr.h"


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







#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(px)
{
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"sp_counted_base.h"
#include"sp_counted_impl.h"


class shared_count
{
public:
template<class Y>
shared_count(Y *p) : pi_(new sp_counted_impl_xx<Y>(p))
{
cout<<"Create shared_count 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<iostream>
using namespace std;


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_H
#define _SP_COUNTED_IMPL_H


#include"sp_counted_base.h"


template<class T>
class sp_counted_impl_xx : public sp_counted_baes
{
public:
sp_counted_impl_xx(T *px) : px_(px)
{
cout<<"Create sp_counted_impl_xx Object."<<endl;
}
~sp_counted_impl_xx()
{
cout<<"Free sp_counted_impl_xx Object."<<endl;
}
private:
T *px_;
};


#endif

 

 

 

整体框架如图:

 

 

下面是sharead_ptr的析构流程:

 

 

就这么多,新手做的笔记,希望多做指正

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值