1. c++智能指针中,c++的memory文件中,有auto_ptr等各种关于智能指针的东西,shared_ptr,weak_ptr在C++11中已经成为标准。

也看了ogs的智能指针,每次引用起来比较麻烦,规则也多。方便的是自动的引用计数,可选线程安全。

为方便 写了个公用类,如下:

#ifndef _test_share_ptr_h__
#define _test_share_ptr_h__ #define null 0
class student
{
public:
student();
student(float score_)
:scores(score_)
{ }
virtual ~ student();
public:
char* all_class_name;
float scores;
private: }; student:: student()
{
} student::~ student()
{
if (null != all_class_name)
{
delete []all_class_name;
all_class_name = null;
}
} #endif

2.auto_ptr

功能相对简单,只能负责释加入到auto_ptr中的基类,并且基类中没有单独的到堆上申请内存。

写的两个函数测试,一个函数类:

void mem_ptr_student_new()
{
int byte_numbers = 1024;
for (int i = 0; i < count_times;i++)
{
student* pri_test_stu = new student;
mem::auto_ptr<student> pri_student_share_ptr(pri_test_stu);
pri_student_share_ptr->all_class_name = new char[byte_numbers];
for (int j = 0; j < byte_numbers;j++)
{
pri_student_share_ptr->all_class_name[j] = j;
}
pri_student_share_ptr->scores = (float)(i + 10);
}
} typedef std::vector<mem::auto_ptr<student>> mem_vector_student;
void mem_ptr_student_vector_new()
{
int byte_numbers = 1024;
mem_vector_student pri_test_vector;
/*
	mem::auto_ptr_ref<mem_vector_student> pri_auto_ref(&pri_test_vector);
mem::auto_ptr<mem_vector_student> pri_vector_student_share_ptr(pri_auto_ref);
for (int i = 0; i < count_times;i++)
{
mem::auto_ptr<student> pri_student_share_ptr(new student);
pri_student_share_ptr->all_class_name = new char[byte_numbers];
for (int j = 0; j < byte_numbers;j++)
{
pri_student_share_ptr->all_class_name[j] = j;
}
pri_student_share_ptr->scores = (float)(i + 10);
pri_vector_student_share_ptr->push_back(pri_student_share_ptr);
}*/
}

结果很明显,对于这样的类,char* all_class_name 在使用中自动申请了内存,auto_ptr很明显无能为力。内存泄露明显,所以第二个函数,stl vector的使用更不用多说,

一样不行。

摘抄了一段auto_ptr使用说明:

/*---------------------------mem_auto_ptr-------------------------------------*/
/*
若下函数,使用mem::auto_ptr时候,不会自动调用student函数的析构,造成内存泄露。
摘抄部分说明: * 1)auto_ptr不能共享所有权,即不要让两个auto_ptr指向同一个对象。
* * 2)auto_ptr不能指向数组,因为auto_ptr在析构的时候只是调用delete,而数组应该要调用delete[]。
* * 3)auto_ptr只是一种简单的智能指针,如有特殊需求,需要使用其他智能指针,比如share_ptr。
* * 4)auto_ptr不能作为容器对象,STL容器中的元素经常要支持拷贝,赋值等操作,在这过程中auto_ptr会传递所有权,那么source与sink元素之间就不等价。
*/

3.  别人写的一个share_ptr,用来测试和比较说明。

此类功能复杂,代码相对多。不过,挺好用。

若有问题,随时联系,可删除。

#ifndef __smart_shared_ptr_h__
#define __smart_shared_ptr_h__ #define null 0
namespace smart
{
class shared_ptr_reference_count
{
public:
shared_ptr_reference_count()
{
_reference_count = 1;
} virtual ~shared_ptr_reference_count()
{
} void grab()
{
_reference_count++;
} size_t drop()
{
_reference_count--;
return _reference_count;
} size_t get_reference_count()
{
return _reference_count;
}
private:
size_t _reference_count;
}; class shared_ptr_reference_destory
{
public:
virtual ~shared_ptr_reference_destory(){};
}; template<class t>
class smart_shared_ptr; class smart_shared_ptr_shadow
{
public:
smart_shared_ptr_shadow()
: _reference_instance(null)
, _reference_count(null)
, _reference_destory(null)
{
} smart_shared_ptr_shadow(void *instance_, shared_ptr_reference_count* reference_count_, shared_ptr_reference_destory* reference_destory_)
: _reference_instance(instance_)
, _reference_count(reference_count_)
, _reference_destory(reference_destory_)
{
if(_reference_count != null)
{
_reference_count->grab();
}
} ~smart_shared_ptr_shadow()
{
if(_reference_count == null)
{
return;
} if(_reference_count->drop() == 0){
delete _reference_destory;
_reference_destory = null; delete _reference_count;
_reference_count = null;
}
} smart_shared_ptr_shadow(const smart_shared_ptr_shadow& right_)
{
if(right_._reference_count != null){
right_._reference_count->grab();
} _reference_instance = right_._reference_instance;
_reference_count = right_._reference_count;
_reference_destory = right_._reference_destory;
} template<class t_>
smart_shared_ptr<t_> to_shared_ptr()
{
return smart_shared_ptr<t_>((t_*)_reference_instance, _reference_count);
} template<class t_>
operator smart_shared_ptr<t_>()
{
return to_shared_ptr<t_>();
} smart_shared_ptr_shadow& operator = (const smart_shared_ptr_shadow& right_)
{
if(right_._reference_count != null)
{
right_._reference_count->grab();
} if(_reference_count != null)
{
if(_reference_count->drop() == 0)
{
delete _reference_destory;
_reference_destory = null; delete _reference_count;
_reference_count = null;
}
} _reference_instance = right_._reference_instance;
_reference_count = right_._reference_count;
_reference_destory = right_._reference_destory;
return *this;
} bool operator == (const smart_shared_ptr_shadow& right_) const
{
return (_reference_instance == right_._reference_instance);
} operator bool() const
{
return _reference_count != null;
}
private:
void* _reference_instance;
shared_ptr_reference_count* _reference_count;
shared_ptr_reference_destory* _reference_destory;
}; template<class t>
class smart_shared_ptr
{
class shared_ptr_reference_destory_impl
: public shared_ptr_reference_destory
{
public:
shared_ptr_reference_destory_impl(t* reference_instance_)
{
this->_reference_instance = reference_instance_;
} virtual ~shared_ptr_reference_destory_impl()
{
delete _reference_instance;
}
private:
t* _reference_instance;
}; public:
smart_shared_ptr()
: _reference_count(null)
, _reference_instance(null)
{ } smart_shared_ptr(t* instance_)
: _reference_count(new shared_ptr_reference_count)
, _reference_instance(instance_)
{
} smart_shared_ptr(t* instance_, shared_ptr_reference_count* reference_count_)
: _reference_count(reference_count_)
, _reference_instance(instance_)
{
if(_reference_count != null)
{
_reference_count->grab();
}
} ~smart_shared_ptr()
{
if(_reference_count == null)
{
return;
} if(_reference_count->drop() == 0)
{
delete _reference_instance;
_reference_instance = null; delete _reference_count;
_reference_count = null;
}
} t* operator -> ()
{
return _reference_instance;
} smart_shared_ptr(const smart_shared_ptr& right_)
{
if(right_._reference_count != null)
{
right_._reference_count->grab();
} _reference_instance = right_._reference_instance;
_reference_count = right_._reference_count;
} smart_shared_ptr_shadow to_shared_ptr_shadow()
{
return smart_shared_ptr_shadow(_reference_instance, _reference_count, new shared_ptr_reference_destory_impl(_reference_instance));
} template<class t_>
smart_shared_ptr<t_> to_shared_ptr()
{
return smart_shared_ptr<t_>((t_*)_reference_instance, _reference_count);
} template<class t_>
operator smart_shared_ptr<t_>()
{
return to_shared_ptr<t_>();
} operator smart_shared_ptr_shadow()
{
return to_shared_ptr_shadow();
} smart_shared_ptr& operator = (const smart_shared_ptr& right_)
{
if(right_._reference_count != null)
{
right_._reference_count->grab();
} if(_reference_count != null)
{
if(_reference_count->drop() == 0)
{
delete _reference_instance;
_reference_instance = null; delete _reference_count;
_reference_count = null;
}
} _reference_instance = right_._reference_instance;
_reference_count = right_._reference_count; return *this;
} template<class t_>
bool operator == (const smart_shared_ptr& right_) const
{
return (_reference_instance == right_.reference_instance);
} operator bool() const
{
return _reference_count != null;
} bool is_null() const
{
return _reference_count != null;
}
private:
shared_ptr_reference_count* _reference_count;
t* _reference_instance;
}; #endif

同样的测试代码,只是里面类名称改变一下。如下:

void smart_ptr_student_new()
{
int byte_numbers = 1024;
for (int i = 0; i < count_times;i++)
{
smart_shared_ptr<student> pri_student_share_ptr = new student;
pri_student_share_ptr->all_class_name = new char[byte_numbers];
for (int j = 0; j < byte_numbers;j++)
{
pri_student_share_ptr->all_class_name[j] = j;
}
pri_student_share_ptr->scores = (float)(i + 10);
}
} typedef std::vector<smart_shared_ptr<student>> vector_student;
void smart_ptr_student_vector_new()
{
int byte_numbers = 1024;
smart_shared_ptr<vector_student> pri_vector_student_share_ptr = new vector_student();
for (int i = 0; i < count_times;i++)
{
smart_shared_ptr<student> pri_student_share_ptr = new student;
pri_student_share_ptr->all_class_name = new char[byte_numbers];
for (int j = 0; j < byte_numbers;j++)
{
pri_student_share_ptr->all_class_name[j] = j;
}
pri_student_share_ptr->scores = (float)(i + 10);
pri_vector_student_share_ptr->push_back(pri_student_share_ptr);
}
}

结果:很明显,可管理类的对象指针和vector中的对象指针,因为重载了等号,括号,实时可以记录指针的使用次数,并处理了析构。计数的做为个类来处理,比有的智能

指针用个static的变量来好很多。

但是各种此类型的指针可以相互赋值,因为里面用的指针一律是void* 造成的。

3. 一个简单的ptr

不知道是否有问题啊。目前看起来还行。

#ifndef __m_smart_ptr_h__
#define __m_smart_ptr_h__ #include <iostream>
#include <stdexcept>
using namespace std; #define test_smart_ptr_cout
namespace s_smart
{
template <typename T>
class simple_smart_ptr
{
public:
simple_smart_ptr(T *p = 0): ptr(p), p_use_count(new size_t(1))
{
} simple_smart_ptr(const simple_smart_ptr& src): ptr(src.ptr), p_use_count(src.p_use_count)
{
++*p_use_count;
} simple_smart_ptr& operator= (const simple_smart_ptr& rhs) {
// self-assigning is also right
++*rhs.p_use_count;
decrUse();
ptr = rhs.ptr;
p_use_count = rhs.p_use_count;
return *this;
} T *operator->()
{
if (ptr)
return ptr;
throw std::runtime_error("access through NULL pointer");
}
const T *operator->() const
{
if (ptr)
return ptr;
throw std::runtime_error("access through NULL pointer");
} T &operator*()
{
if (ptr)
return *ptr;
throw std::runtime_error("dereference of NULL pointer");
} const T &operator*() const
{
if (ptr)
return *ptr;
throw std::runtime_error("dereference of NULL pointer");
} ~simple_smart_ptr()
{
decrUse();
#ifdef test_smart_ptr_cout
std::cout<<"simple_smart_ptr: Destructor"<<std::endl; // for testing
#endif
} private:
void decrUse()
{
if (--*p_use_count == 0) {
delete ptr;
delete p_use_count;
}
}
T *ptr;
size_t *p_use_count;
};
} #endif

同样的测试过程,均可用。对类的指针有删除能力。

以上的智能指针的操作没有线程安全。

在osg的有一个宏定义来定义,是否启用原子操作的,_OSG_REFERENCED_USE_ATOMIC_OPERATIONS,对于计数的操作是安全的。

完结了!

本文代码下载地址:http://download.csdn.net/detail/cartzhang/7004199

形式是多种的,内容是一致的。

若有问题,请及时指正!

c++智能指针使用笔记的更多相关文章

  1. C++11智能指针读书笔记;

    智能指针是一个类对象,而非一个指针对象. 原始指针:通过new建立的*指针 智能指针:通过智能指针关键字(unique_ptr, shared_ptr ,weak_ptr)建立的指针 它的一种通用实现 ...

  2. C++的智能指针学习笔记(初)

    C++ primer plus 16.2节介绍了auto_ptr,该模板类在C++11中已弃用,目前已被shared_ptr代替. auto_ptr又叫做智能指针,用于管理动态内存分配的用法. 为什么 ...

  3. C++中的智能指针、轻量级指针、强弱指针学习笔记

    一.智能指针学习总结 1.一个非const引用无法指向一个临时变量,但是const引用是可以的! 2.C++中的delete和C中的free()类似,delete NULL不会报"doubl ...

  4. EC笔记:第三部分:17、使用独立的语句将newed对象放入智能指针

    一般的智能指针都是通过一个普通指针来初始化,所以很容易写出以下的代码: #include <iostream> using namespace std; int func1(){ //返回 ...

  5. c++学习笔记——智能指针

    智能指针是为了便于管理动态内存,能够自动管理释放所指向的对象. 智能指针共有三种:1.shared_ptr允许多个指针指向同一个对象:2.unique_ptr独占所指向的对象:3.weak_ptr是一 ...

  6. osg(OpenSceneGraph)学习笔记1:智能指针osg::ref_ptr<>

    OSG的智能指针,osg::ref_ptr<> osg::Referenced类管理引用计数内存块,osg::ref_ptr需要使用以它为基类的其它类作为模板参数. osg::ref_pt ...

  7. 读书笔记_Effective_C++_条款十七:以独立语句将new产生的对象置入智能指针

    int get_int(); void f(shared_ptr<int> a, int); //下面调用 f(new int(3), get_int());//如果是类而不是int就可以 ...

  8. 读书笔记 effective c++ Item 17 使用单独语句将new出来的对象放入智能指针

    1. 可能会出现资源泄漏的一种用法 假设我们有一个获取进程优先权的函数,还有一个在动态分类的Widget对象上根据进程优先权进行一些操作的函数: int priority(); void proces ...

  9. C++ Primer 笔记——智能指针

    1.新的标准库提供了两种智能指针类型,shared_ptr允许多个指针指向同一个对象,unique_ptr则独占所指的对象.标准库还定义了一个名为weak_ptr的伴随类,它是一种弱引用,指向shar ...

随机推荐

  1. Android自己定义效果——随机抽奖

    那天逛android开源码的时候,看到一个wheel menu的自己定义效果,就是类似人家的那种转盘抽奖,把人家project看了下.认为非常好玩.可是不想在他上面改,于是就自己想了一个类似的随即抽奖 ...

  2. PHP CLI模式下的多进程应用分析

    PHP在非常多时候不适合做常驻的SHELL进程, 他没有专门的gc例程, 也没有有效的内存管理途径. 所以假设用PHP做常驻SHELL, 你会常常被内存耗尽导致abort而unhappy 并且, 假设 ...

  3. eclipse部署maven web项目到tomcat服务器时,没有将lib、web.xml复制过去的解决办法

    我这几天在写项目的时候发现自己以前的项目能够访问,隔一段时间写的这个项目却不能够访问,没有发现代码的逻辑错,但是就是访问不了jsp页面,项目一发布就是出现404错误,后来发现原来是发布到tomcat上 ...

  4. Kinect 开发 —— 进阶指引 (下)

    运动识别 利用运动识别(motion detection)来进行近景识别是最有意思的一种方式.实现运动识别的基本原理是设置一个起始的基准RGB图像,然后将从摄像头获取的每一帧影像和这个基准图像进行比较 ...

  5. (转)OpenCV 基本知识框架

    以下是对<学习OpenCV>一书知识框架的简单梳理 转自:http://blog.chinaunix.net/uid-8402201-id-2899695.html 一.基础操作      ...

  6. kill&&pkill&&killall---删除执行中的程序

    命令功能: 发送指定的信号到相应进程.不指定型号将发送SIGTERM(15)终止指定进程.如果无法终止该程序可用“-KILL” 参数,其发送的信号为SIGKILL(9) ,将强制结束进程 使用ps命令 ...

  7. HTML中行内元素与块级元素有哪些及区别

    二.行内元素与块级元素有什么不同? 块级元素和行内元素的区别是,块级元素会占一行显示,而行内元素可以在一行并排显示. 通过样式控制,它们可以相互转换. 1.尺寸-块级元素和行内元素之间的一个重要的不同 ...

  8. android缩放动画的两种实现方法

    在android开发.我们会常常使用到缩放动画,普通情况下缩放动画有两种实现方式.一种是直接通过java代码去实现,第二种是通过配置文件实现动画,以下是两种动画的基本是用法: Java代码实现: // ...

  9. WIN8.1 上安装 debian8.7 遇到的问题及解决方法

    WIN8.1 上安装 debian8.7 遇到的问题及解决方法 参照百度经验 <win7下硬盘安装debian7> ( http://jingyan.baidu.com/article/8 ...

  10. THC=TERMINAL HANDLING CHARGE,碼頭操作費

    THC=TERMINAL HANDLING CHARGE,碼頭操作費