1.智能指针是RAII思想的一种产品, RAII:Resource Acquistion Is Initialization ,资源分配就初始化,定义一个类来封装资源的分配和释放。在构造函数里完成资源分配初始化,在析构函数里完成资源的清理。 通常是经由类模板来实现。借由模板来达成泛型,通常借由类的析构函数来达成自动释放指针所指向的内存或对象。
第一个阶段(C++98):
auto_ptr:自动指针,它的主要思想是管理权转移,但其存在很大的缺陷,当要进行拷贝构造或者赋值相关操作时,原来的智能指针就失去意义,此时只有新的智能指针可以使用。简单点说,就是任何时候只能有一个智能指针指向那块空间,这样在使用上造成了很大的不便。
第二个阶段(C++03):
即第三方库Boost库中的智能指针:
scoped_ptr:守卫指针,它的主要思想就是防拷贝。
shared_ptr:共享指针,顾名思义就是共享同一块空间,它的主要思想是引入引用计数,但存在循环引用的缺陷。
weak_ptr:弱指针,它主要用来配合共享指针解决共享指针的循环引用的缺陷。
第三阶段(C++11):
unique_ptr:如同boost库中的scoped_ptr,主要思想就是防拷贝。
shared_ptr:它的主要思想是引入引用计数,但存在循环引用的缺陷。
weak_ptr:弱指针,它主要用来配合共享指针解决共享指针的循环引用的缺陷。
2.auto_ptr:自动指针,它的主要思想是管理权转移,但其存在很大的缺陷,当要进行拷贝构造或者赋值相关操作时,原来的智能指针就失去意义,此时只有新的智能指针可以使用。简单点说,就是任何时候只能有一个智能指针指向那块空间,这样在使用上造成了很大的不便。
scoped_ptr:守卫指针,它的主要思想就是防拷贝。
shared_ptr: 共享指针,顾名思义就是共享同一块空间,它的主要思想是引入引用计数,但存在循环引用的缺陷。
weak_ptr: 弱指针,它主要用来配合共享指针解决共享指针的循环引用的缺陷。
3.
#include<string>
class AutoPtr // 模拟实现auto_ptr
{
public:
AutoPtr(T* ptr = NULL)
:_ptr(ptr)
{}
AutoPtr(AutoPtr<T>& ap)
{
_ptr = ap._ptr;
ap._ptr = NULL;
}
AutoPtr<T>& operator = (AutoPtr<T>& ap)
{
if (_ptr != ap._ptr)
{
if (_ptr)
{
delete _ptr;
}
_ptr = ap._ptr;
ap._ptr = NULL;
}
return *this;
}
{
return *_ptr;
}
{
return _ptr;
}
{
cout << "~AutoPtr()" << endl;
if (_ptr)
{
delete _ptr;
}
}
private:
T* _ptr;
};
{
AutoPtr<int>ptr1(new int(10));
AutoPtr<int>ptr2(ptr1);
AutoPtr<int>ptr3(ptr2);
cout << *ptr3 << endl;
template <class T>
class ScopedPtr //scoped_ptr的模拟实现
{
public:
ScopedPtr(T* ptr = NULL)
:_ptr(ptr)
{}
T* operator ->()
{
return _ptr;
}
T& operator *()
{
return *_ptr;
}
T* _ptr;
ScopedPtr<T>(ScopedPtr<T>& ap);
ScopedPtr<T>& operator = (ScopedPtr<T>& ap);
};
{
ScopedPtr<int>ptr1(new int(6));
}
class SharedPtr
{
public:
SharedPtr(T* ptr = NULL)
:_ptr(ptr)
: _refcount(new int(1))
{}
{
if (_ptr != sp._ptr)
{
if (--(*_refcount) == 0)
{
delete _ptr;
delete _refcount;
}
_ptr = sp._ptr;
_refcount = sp._refcount;
(*_refcount)++;
}
return *this;
}
T* GetPtr()
{
return _ptr;
}
T* operator->()
{
return _ptr;
}
T& operator*()
{
return *_ptr;
}
{
if (--(*_refcount) == 0)
{
delete _ptr;
delete _refcount;
}
}
private:
T* _ptr;
T* _refcount;
};
{
SharedPtr<int>ptr1(new int(1));
SharedPtr<int>ptr2(ptr1);
SharedPtr<int>ptr3(new int(3));
ptr1 = ptr3;
}
class WeakPtr
{
public:
WeakPtr()
:_ptr(NULL)
{}
WeakPtr(SharedPtr < T& s)
:_ptr(s.GetPtr())
{}
T* GetPtr()
{
return _ptr;
}
T* operator->()
{
return _ptr;
}
T& operator*()
{
return *_ptr;
}
private:
T* _ptr;
};
struct ListNode
{
WeakPtr<ListNode> _prev;
WeakPtr<ListNode> _next;
~ListNode()
{
cout << "~ListNode()" << endl;
}
};
void TestWeakPtr()
{
SharedPtr<ListNode> cur = new ListNode;
SharedPtr<ListNode> next = new ListNode;
cur->_next = next;
next->_prev = cur;
}
1. 当只剩下最后一个引用的时候需要手动打破循环引用释放对象。
2. 当A的生存期超过B的生存期的时候,B改为使用一个普通指针指向A。
3. 使用弱引用的智能指针打破这种循环引用。