c++智能指针实现
来源:互联网 发布:丁香园insight数据库 编辑:程序博客网 时间:2024/06/03 16:49
什么是智能指针,通俗来说,是通过基本类型(模板类)指针,构造类的对象,当此对象销毁时,即调用此对象的析够函数时,释放此指针。也就是用栈中的空间来管理堆中的内存。
STL一共给我们提供了四种智能指针:auto_ptr、unique_ptr、shared_ptr和weak_ptr
auto_ptr和unique_ptr要慎用,原因一样。当auto_ptr的一个对象p1赋值给另一个对象p2时,p1对象的基本类型指针会转移给p2,也就是说,p1对象的指针已指向NULL了。两个所不同的就是,auto_ptr赋值时,编译器允许你这么做,而unique_ptr赋值时,编译器压根不让你这么做,直接报错。
例如
std::auto_ptr p1(new std::string(“auto”) );
std::auto_ptr p2 = p1;
std::string str = *p1;
当再去操作p1内指针时,程序崩溃,因为p1内指针已指向NULL。
而 std::unique_ptr p3(new std::string(“auto”) );
std::unique_ptr p4 = p3;
第二句代码直接编译不通。
无论如何,不太推荐使用它们,因为当你把此两种智能指针放入数组,或者作为参数传递时,(即出现赋值操作时,例如P1 = PS[i]。那么你这个数组里的内容已经废了。)均会对代码造成很大的风险。
而shared_ptr则完全避免了上述问题,因为,此类的内部每进行一次赋值操作时,记录了此指针的引用计数加1。析够此对象时, 引用计数会自动减1。当引用计数为零时,再去释放此指针。唯一缺点,效率上肯定相对于前两种,略低。但是,既然想用对象代替指针,此效率可以忍受,要不然,不推荐使用智能指针。
weak_ptr为辅助shared_ptr出现,属于弱指针类型,而shared_ptr为强指针类型,当shared_ptr的两个对象出现互相引用时,释放后,引用计数永久为1,也就造成了内存泄露。现在就可以利用weak_ptr定义类内部引用shared_ptr对象的对象类型。shared_ptr因为不用多次引用,进而效率也相对较高。
借鉴osg,ref_ptr就是强指针类型,observer_ptr是弱指针类型。
整理osg,强指针类型代码,去除引用对象的观察者,线程控制等代码,整理代码如下(自己所定义的类继承Reference类即可):
template
class ref_ptr
{
public:
typedef T element_type;
ref_ptr() : _ptr(0) {} ref_ptr(T* ptr) : _ptr(ptr) { if (_ptr) _ptr->ref(); } ref_ptr(const ref_ptr& rp) : _ptr(rp._ptr) { if (_ptr) _ptr->ref(); } template<class Other> ref_ptr(const ref_ptr<Other>& rp) : _ptr(rp._ptr) { if (_ptr) _ptr->ref(); } ~ref_ptr() { if (_ptr) _ptr->unref(); _ptr = 0; } ref_ptr& operator = (const ref_ptr& rp) { assign(rp); return *this; } template<class Other> ref_ptr& operator = (const ref_ptr<Other>& rp) { assign(rp); return *this; } inline ref_ptr& operator = (T* ptr) { if (_ptr==ptr) return *this; T* tmp_ptr = _ptr; _ptr = ptr; if (_ptr) _ptr->ref(); // unref second to prevent any deletion of any object which might // be referenced by the other object. i.e rp is child of the // original _ptr. if (tmp_ptr) tmp_ptr->unref(); return *this; } // comparison operators for ref_ptr. bool operator == (const ref_ptr& rp) const { return (_ptr==rp._ptr); } bool operator == (const T* ptr) const { return (_ptr==ptr); } friend bool operator == (const T* ptr, const ref_ptr& rp) { return (ptr==rp._ptr); } bool operator != (const ref_ptr& rp) const { return (_ptr!=rp._ptr); } bool operator != (const T* ptr) const { return (_ptr!=ptr); } friend bool operator != (const T* ptr, const ref_ptr& rp) { return (ptr!=rp._ptr); } bool operator < (const ref_ptr& rp) const { return (_ptr<rp._ptr); }// follows is an implmentation of the "safe bool idiom", details can be found at:// http://en.wikibooks.org/wiki/More_C%2B%2B_Idioms/Safe_bool// http://lists.boost.org/Archives/boost/2003/09/52856.phppublic: T& operator*() const { return *_ptr; } T* operator->() const { return _ptr; } T* get() const { return _ptr; } bool operator!() const { return _ptr==0; } // not required bool valid() const { return _ptr!=0; } /** release the pointer from ownership by this ref_ptr<>, decrementing the objects refencedCount() via unref_nodelete() to prevent the Object * object from being deleted even if the reference count goes to zero. Use when using a local ref_ptr<> to an Object that you want to return * from a function/method via a C pointer, whilst preventing the normal ref_ptr<> destructor from cleaning up the object. When using release() * you are implicitly expecting other code to take over management of the object, otherwise a memory leak will result. */ T* release() { T* tmp=_ptr; if (_ptr) _ptr->unref_nodelete(); _ptr=0; return tmp; } void swap(ref_ptr& rp) { T* tmp=_ptr; _ptr=rp._ptr; rp._ptr=tmp; }private: template<class Other> void assign(const ref_ptr<Other>& rp) { if (_ptr==rp._ptr) return; T* tmp_ptr = _ptr; _ptr = rp._ptr; if (_ptr) _ptr->ref(); // unref second to prevent any deletion of any object which might // be referenced by the other object. i.e rp is child of the // original _ptr. if (tmp_ptr) tmp_ptr->unref(); } template<class Other> friend class ref_ptr; T* _ptr;
};
class Reference
{
public:
Reference(){ _refCount = 0;};
virtual ~Reference(void){};
public:
unsigned long ref(){ return ++_refCount;};unsigned long unref_nodelete(){ return --_refCount;};unsigned long unref(){ int newRef = --_refCount; if( newRef == 0 ) delete this; return newRef;};int referenceCount() const{ return _refCount;}
private:
unsigned long _refCount;
};
- 【C++】智能指针的实现
- [c++]智能指针的实现
- C 语言实现智能指针
- 【C++】智能指针auto_ptr的简单实现
- C++(智能指针的设计与实现)
- [C/C++] 智能指针的实现及原理
- c++:智能指针
- C++:智能指针
- 【C++】智能指针
- 【C++】智能指针
- C++PJ智能指针
- 【c++】智能指针
- 【C++】智能指针auto_ptr
- C++,智能指针
- C++,boost智能指针
- 智能指针模拟C
- [C++]智能指针
- 【C++】 浅析智能指针
- GameExit—PC版
- 你是如何自学 Python 的?
- 【工作笔记】微信公众号页面摇一摇+触发音效
- Android多线程之Handler
- matlab矩阵转置
- c++智能指针实现
- HttpClient使用详解
- java笔试面试题--int数组的默认值
- shell学习整理(6)-数组和关联数组
- 《跃迁》思维导图教你如何练就高手之路
- Spark Sort Based Shuffle内存分析
- 网站图片收录与展现的维度
- iOS使用sonar进行代码分析
- 冒泡算法----Java