1.智能指针存在的意义
c++不像java等语言有自动的内存回收机制,程序员每次都必须对自己new出来的堆内存进行手动delete,这样做固然减少了系统对于内存的管理开销,给程序员极大地自主性,但是如果忘记delete分配的内存,就会造成内存泄漏,甚至导致程序崩溃。
智能指针在c++11中存在的意义就在于解决内存泄漏问题,对于没有指向的内存进行自动释放。常见的智能指针有std::auto_ptr, std::shared_ptr, std::unique_ptr等等。
2.智能指针的使用方式以及具体原理
对于编译器来说,智能指针实际上是一个栈对象,并非指针类型,在栈对象生命期即将结束时,智能指针通过析构函数释放它管理的堆内存。智能指针指向堆内存,一般的实现形式是引用计数。
智能指针将一个计数器与类指向的对象相关联,用来最终该类有多少个对象共享同一个指针。具体来说:
1. 每次创建新对象的时候,初始化指针并将引用计数设置为1
2. 当对象作为另一个对象副本而创建的时候,拷贝其指针,增加与之对应的引用计数
3. 对一个已有对象进行赋值的时候,如果指向同一对象,什么也不做,如果指向不同对象,赋值运算符减少左操作数所指对象的引用计数(如果为0,那么是方向应内存),增加右操作数所指对象的引用计数
4. 当一个只能指针离开当前的有效范围被释放掉的时候,减少对应的引用计数,如果为0,那么释放内存
template <class T>
class smartpointer
{
private:
T *_ptr;
public:
smartpointer(T *p) : _ptr(p) //构造函数
{
}
T& operator *() //重载*操作符
{
return *_ptr;
}
T* operator ->() //重载->操作符
{
return _ptr;
}
~smartpointer() //析构函数
{
delete _ptr;
}
};
// 定义仅由HasPtr类使用的U_Ptr类,用于封装使用计数和相关指针
// 这个类的所有成员都是private,我们不希望普通用户使用U_Ptr类,所以它没有任何public成员
// 将HasPtr类设置为友元,使其成员可以访问U_Ptr的成员
class U_Ptr
{
friend class HasPtr;
int *ip;
size_t use;
U_Ptr(int *p) : ip(p) , use(1)
{
cout << "U_ptr constructor called !" << endl;
}
~U_Ptr()
{
delete ip;
cout << "U_ptr distructor called !" << endl;
}
};