C++ 智能指针

    技术2024-08-06  68

    (1)什么是智能指针:

    智能指针(smart pointer)是存储指向动态分配(堆)对象指针的类,用于生存期控制,能够确保自动正确的销毁动态分配的对象,防止内存泄露(利用自动调用类的析构函数来释放内存)。

    原理:智能指针类将一个计数器与类指向的对象相关联,通过计数来记录该类有多少个对象共享同一指针。每次创建类的新对象时,初始化指针并将引用计数置1;当对象作为另一对象的副本而创建时,拷贝构造函数拷贝指针并增加与之相应的引用计数;调用析构函数时,构造函数减少引用计数(如果引用计数减至0,则删除基础对象)。 

    (2)为什么要用智能指针:

           手动malloc/new出来的资源,容易忘记free/delete;中途抛出异常,无法释放资源。

    (3)常见智能指针介绍:

         C++中有四个智能指针,auto_ptr、unique_ptr、shared_ptr、weak_ptr,后三个是C++11支持,第一个已经被11弃用。

    auto_ptr:

    采用所有权模式,不支持复制和赋值,但是复制和赋值时不会报错,而是剥夺所有权给新的指针。

    auto_ptr<string> p1 (new string (“abcd”));                //声明智能指针p1

    auto_ptr<string> p2;                                                   //声明智能指针p2

    p2 = p1;                                                                       //不报错,但再次访问p1会出错

    unique_ptr:

           替换auto_ptr,实现独占是拥有或者严格拥有,保证同一时间内只有一个智能指针拥有该对象,复制和赋值会报错。

    unique _ptr<string> p1 (new string (“abcd”));                     //声明智能指针p1

    unique_ptr<string> p2;                                                      //声明智能指针p2

    p2 = p1;                                                                              //报错!

    shared_ptr:

           实现共享式拥有,可随意的复制和赋值,通过计数器的机制记录资源被几个指针所共享,当计数器为0时,资源被释放。

           可用use_count()来查看资源所有者的个数,unique()返回资源是否独占所有权,

    weak_ptr:

           其是一种不控制生命周期的智能指针,指向一个shared_ptr管理的资源对象(shared_ptr是对该资源进行内存管理的强引用),weak_ptr只是提供了对管理资源对象的一个访问手段。

           weak_ptr用于解决shared_ptr相互引用时产生的死锁问题,若两个shared_ptr相互引用会导致计数器永远不为0,从而无法释放资源,这也是智能指针的内存泄漏问题

    (4)智能指针的实现:

    #include<bits/stdc++.h> using namespace std; template<typename T> //模板类:T class SmartPointer{ public: //构造函数 SmartPointer(T* p = 0):_ptr(p),_reference_count(new size_t){ if(p) *_reference_count = 1; else *_reference_count = 0; } //拷贝构造函数 SmartPointer(const SmartPointer& src){ if(this != &src){ _ptr = src._ptr; _reference_count = src._reference_count; (*_reference_count)++; } } //重载赋值操作符 SmartPointer& operator=(const SmartPointer& src){ if(_ptr == src._ptr){ return *this; } releaseCount(); _ptr = src._ptr; _reference_count = src._reference_count; (*_reference_count)++; return *this; } //重载操作符* T& operator*(){ if(_ptr) return *_ptr; } //重载操作符-> T* operator->(){ if(_ptr) return _ptr; } //析构函数 ~SmartPointer(){ if(--(*_reference_count)==0){ delete _ptr; delete _reference_count; } } private: T* _ptr; //指针 size_t* _reference_count; //计数器 //删除指针 void releaseCount(){ if(_ptr){ (*_reference_count)--; if((*_reference_count)==0){ delete _ptr; delete _reference_count; } } } }; int main(){ SmartPointer<char> cp1(newchar('a')); SmartPointer<char> cp2(cp1); SmartPointer<char> cp3; cp3=cp2; cp3=cp1; cp3=cp3; SmartPointer<char> cp4(newchar('b')); cp3 = cp4; }

     

    Processed: 0.013, SQL: 9