zoukankan      html  css  js  c++  java
  • C++智能指针

    1、智能指针概述

    智能指针本身是个类,程序员在为指针进行内存分配后,可能忘记使用delete销毁内存,为了避免这个问题,出现了智能指针。智能指针在创建时调用构造函数,在消亡时(超出使用范围以后)自动调用析构函数,这样就起到一个内存回收的作用。智能指针的对象都是栈上创建。

    2、四种智能指针讲解

    2.1 std::auto_ptr

    std::auto_ptr属于C++98方案,C++11已经弃用。不支持复制(拷贝构造函数)和赋值(operator =),但进行该操作时编译器不会报错。该指针采用所有权模式,假设有std::auto_ptr p1和p2,此时p1已经初始化,将p1赋值给p2,则p2剥夺了p1的所有权,当程序运行时访问p1会报错,因为此时p1所指位置并不确定,因此存在潜在内存问题。

    2.2 std::unique_ptr

    std::unique_ptr是C++11中新增的用来替代auto_ptr的智能指针。std::unique_ptr实现独占式拥有或严格拥有概念,保证同一时间内只有一个只能指针可以指向该对象,同时智能指针本身是一个类,在对象生命周期结束以后会自动调用析构函数释放内存,从而避免了内存泄漏问题。那么刚才说的有关std::auto_ptr出现的情况如果用std::unique_ptr替换则无法通过编译,需要赋值时调用std::move方法。

    2.3 std::shared_ptr

    std::shared_ptr实现共享式拥有,多个智能指针可以指向一个相同对象,该对象和其相关资源会在最后一个引用被销毁时释放。std::shared_ptr是为了解决std::auto_ptr在对象所有权上的局限性,在使用引用计数的机制上提供了可以共享所有权的智能指针。

    2.4 std::weak_ptr

    std::weak_ptr是一中不控制对象生命周期的智能指针,属于弱引用。它指向一个std::shared_ptr管理的对象,其设计的目的是为了配合std::shared_ptr的使用,它只能从一个std::shared_ptr或另一个std::weak_ptr对象构造,其构造和析构不会引起引用计数的增加或减少。std::weak_ptr是用来解决std::shared_ptr相互引用时的死锁问题(如果两个std::shared_ptr相互引用,那么这两个指针的引用计数永远不可能降到0,资源永远不能释放)。

    3、手写实现std::shared_ptr

    #include <memory>
    #include <iostream> ​ template <typename T> class MySharedPtr { private: T *_ptr; size_t *_reference_count;
    // 引用计数操作 void __releaseCount() { if(_ptr) { (*_reference_count)--; if(*_reference_count == 0) { delete _ptr; delete _reference_count; } } } ​ public: // 构造函数 MySharedPtr(T *p = nullptr): _ptr(p), _reference_count(new size_t) { if(p) *_reference_count = 1; else *_reference_count = 0; } // 复制构造函数 MySharedPtr(const MySharedPtr &s_p) { if(this != &s_p) { _ptr = s_p._ptr; _reference_count = s_p._reference_count; (*_reference_count)++; } } // 析构函数 ~MySharedPtr() { if(--(*_reference_count) == 0) { delete _ptr; delete _reference_count; } } // 赋值操作符重载 MySharedPtr& operator=(const MySharedPtr &s_p) { if(_ptr == s_p._ptr) return *this; __releaseCount(); _ptr = s_p._ptr; _reference_count = s_p._reference_count; (*_reference_count)++; return *this; } // ->操作符重载 T* operator->() { if(_ptr) return _ptr; } // 指针取值操作符重载 T& operator*() { if(_ptr) return *_ptr; } };

    // test
    int main()
    {
        int a = 10;
        int *p1 = &a;
        MySharedPtr<int> p2 = p1;
        std::cout << *p2 << std::endl;

        return 0;
    }
     
  • 相关阅读:
    Codeforces 1045C Hyperspace Highways (看题解) 圆方树
    Codeforces 316E3 线段树 + 斐波那切数列 (看题解)
    Codeforces 803G Periodic RMQ Problem 线段树
    Codeforces 420D Cup Trick 平衡树
    Codeforces 295E Yaroslav and Points 线段树
    Codeforces 196E Opening Portals MST (看题解)
    Codeforces 653F Paper task SA
    Codeforces 542A Place Your Ad Here
    python基础 异常与返回
    mongodb 删除
  • 原文地址:https://www.cnblogs.com/horacle/p/14578125.html
Copyright © 2011-2022 走看看