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. POJ——T 3067 Japan

    http://poj.org/problem?id=3067 Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 29474   ...

  2. PIM-DM协议内核触发机制及协议执行机制记录

    PIM-DM和PIM-SM是组播路由ASM(随意信源组播)中的两种不同模式.相对PIM-SM的组播注冊机制.PIM-DM的扩散机制显得更加粗犷. 一.PIM-DM无需向内核注冊pimreg虚接口. 可 ...

  3. 一种基于RGB空间的对照度增强的filter

    今天看前辈博客的时候看到一种新的基于RGB颜色空间的image contrast enhance filter 流浪的鱼link: http://blog.csdn.net/jia20003/arti ...

  4. Image与byte[]数组的相互转换

         近期项目有个需求是关于图片操作的,须要将图片保存到数据库中.经过尝试才知道Image类型文件是不能直接存储到数据库中的.保存之前须要我们做一步转换:将Image转换成字节数组类型Byte ...

  5. xml中控件调用构造方法

    系统控件view有三个构造方法,分别如下 public DrawView(Context context) { super(context); } public DrawView(Context co ...

  6. html的学习思维导图

  7. Redis操作使用规范

    Windows 64位操作系统 Redis 安装包(当前教程版本2.8.12) 百度经验:jingyan.baidu.com 方法/步骤   1 在D盘新建文件夹[redis],右键解压Redis Z ...

  8. SVN无法提交,路径找不到问题的解决方案

    自己有了个云服务器,只在上面搭建了几个博客网站(小雷网等). 我自己的代码,保存在SVNChina上,每年99元.(私人的付费,开源的免费) 云服务器,闲着也是闲着,决定在上面搭建一个属于自己的SVN ...

  9. [PWA] Deal with caches in PWA

    The takeway is to know when we should cache the content? When we should clean the caches? 1. When sh ...

  10. POJ 3461 Oulipo KMP算法题解

    本题就是给出非常多对字符串,然后问一个字符串在另外一个字符串出现的次数. 就是所谓的Strstr函数啦. Leetcode有这道差点儿一模一样的题目. 使用KMP算法加速.算法高手必会的算法了. 另外 ...