c++智能指针

前言:C++中的智能指针有效解决了c++内存管理的问题。

1.背景(缘由)

在c++中,内存管理一直是对于程序员来讲的一个噩梦。通常存在以下3种情况,

1)忘记delete,造成内存泄露;

2)指针指向的内存被释放后(delete),造成指针成为野指针(悬挂指针)。这种情况若再次使用指针会造成未定义或非法内存的错误。

3)重复delete。

对于智能指针,可以有效解决上述的三个问题。

2.定义

智能指针是管理动态分配内存的类,借助引用计数技术,用于生存期控制,智能地在合适的时间完成析构的调用或动态内存的释放。

3.结构

在智能指针类中,包含原始指针和引用计数,以及对->和*运算符的重载。在实现引用计数中,可以使用辅助类和句柄类。以下是辅助类的定义,转自点击打开链接

<pre name="code" class="cpp">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;
    }
};


智能指针类,封装了U_Ptr类。

4.规则

1)每当创建智能指针时,将指针的引用计数初始化为1;

2)当对象赋值过程中,左边的对象引用计数减1,右边的对象引用计数加1;

3)当对象作为另一个对象副本创建时,复制指针并将相应引用计数加1。

4)当引用计数变为0时,调用析构函数或delete释放内存。

5.智能指针举例

点击打开链接

由于 auto_ptr 基于【排他所有权模式】,这意味着:两个指针(同类型)不能指向同一个资源,复制或赋值都会改变资源的所有权。

新加入标准模板库(STL)的智能指针有两个:

shared_ptr:基于引用计数模型。每次有 shared_ptr 对象指向资源,引用计数器就加1;当有 shared_ptr 对象析构时,计数器减1;当计数器值为0时,被指向的资源将会被释放掉。且该类型的指针可复制和可赋值,即其可用于STL容器中。此外,shared_ptr 指针可与多态类型和不完全类型一起使用。主要缺点:无法检测出循环引用(后面会细说),如一颗树,其中既有指向孩子结点的指针又有指向父亲结点的指针,即孩子父亲相互引用。这会造成资源无法释放,从而导致内存泄露。为了 fix 这个问题,引入了另一个智能指针:weak_ptr.

weak_ptr:指向有shared_ptr 指向的资源(即其需要shared_ptr的参与,其辅助 shared_ptr 之用),但是不会导致计数。一旦计数器为0,不管此时指向资源的 weak_ptr 指针有多少,资源都会被释放,而所有的这些 weak_ptr 指针会被标记为无效状态(即 weak_ptr作为观察shared_ptr 的角色存在着,shared_ptr 不会感受到 weak_ptr 的存在)。








發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章