资讯详情

C++智能指针

c 智能指针

提出的初衷是背景,不想手动管理内存,给一个类管理,当类离开自己的功能域时,会自动调用分析函数,释放已申请的内存。

auto_ptr

所有的智能指针都定义为 头文件中

以下是两种基本的初始化方法:

// 方式 1 std::auto_ptr<int> sp1(new int(1)); // 方式 2 std::auto_ptr<int> sp2; sp2.reset(new int(1));

智能指针(smart pointer)sp1 和 sp2 均持有堆上分配的一个 int 对象,值都是 1.这两堆内存都在 sp1 和 sp2 释放时释放。

,例如:

std::auto_ptr<int> sp1(new int(1)); std::auto_ptr<int> sp2(sp1);  // 此时采用复制结构,sp1 将持有的堆对象转移给 sp2 了 std::auto_ptr<int> sp3(new int(1)); std::auto_ptr<int> sp4; sp4 = sp3;  // 此时使用拷贝赋值,sp3 将持有的堆对象转移给 sp4 了

unique_ptr

弥补以上 auto_ptr 提出的缺点 unique_ptr,这种 sp 对其持有的堆内存有唯一的所有权,即 sp 堆积资源的引用计数永远是 1

// 方式 1 std::unique_ptr<int> sp1(new int(2)); // 方式 2 std::unique_ptr<int> sp2; sp2.reset(new int(2)); // 方式 3 std::unique_ptr<int> sp3 = std::make_unique<int>(2); // 推荐使用,更加的安全

使用以下内容时 unique_ptr 核心源码:

template <typename T, typename Deletor> class unique_ptr { // 省略其他代码 public:     // 移动结构函数     unique_ptr(unique_ptr& rhs) {         this->m_pT = rhs.m_pT;         // 源对象释放         rhs.m_pT = nullptr;     }     // 移动赋值     unique_ptr& operator=(unique_ptr& rhs) {         this->m_pT = rhs.m_pT;         // 源对象释放         rhs.m_pT = nullptr;         return *this;     }     // 将复制构造函数和赋值运算符标记为 delete     unique_ptr(const unique_ptr&) = delete;     unique_ptr& operator=(const unique_ptr&) = delete; private:     T* m_pT; };

再测试:

std::unique_ptr<int> sp1(std::make_unique<int>(3)); // 以下代码无法编译 std::unique_ptr<int> sp2(sp1); // 无法编译 std::unique_ptr<int> sp3; sp3 = sp1; // 无法编译  // 以下可以通过编译且成功运行 std::unique_ptr<int> sp4(std::make_unique<int>(4)); std::unique_ptr<int> sp5(std::move(sp4));// 调用移动结构函数 std::unique_ptr<int> sp6; sp6 = std::move(sp5);// 调用移动赋值函数

shared_ptr

与 unique_ptr 对其持有的资源的独占性不同,shared_ptr 可持有多个资源 shared_ptr 分享,每多一个 shared_ptr 引用资源,,指向资源的每一个方向 shared_ptr 对象析构时,,最后一个 shared_ptr 对象析构时,

// 方式 1 std::shared_ptr<int> sp1(new int(5)); // 方式 2 std::shared_ptr<int> sp2; sp2.reset(new int(5)); // 方式 3 std::shared_ptr<int> sp3; sp3 = std::make_shared<int>(5); // 推荐使用

可以使用 use_count() 该方法用于获取当前管理资源的引用计数 reset() 释放引用当前管理资源的方法。

以下为 shared_ptr 实现:

/* 智能指针 sharedPtr 实现 */ template <typename T> class sharedPtr { public:   sharedPtr(T* ptr = nullptr) : _ptr(ptr), _refCount(new int(1)) {}   // 拷贝构造   sharedPtr(const sharedPtr& other) : _ptr(other._ptr), _refCount(other._refCount) {      (*_refCount)  ;    }   // 拷贝赋值   sharedPtr<T>& operator=(const sharedPtr& other) {     // 防止自己赋值     if (this != &other) {       // 本来只剩下我一个方向,释放原始指向       if (--(*(this->_refCount)) == 0) {         delete this->_ptr;         delete this->_refCount;        }       _ptr = other._ptr;       _refCount = other._refCount;       *(_refCount)  ;      }     return *this;    }   // 重载解引用   T& operator*() {     return *(this->_ptr);    }    // 重载箭头   T* operator->() {     return this->_ptr;    }    ~sharedPtr() {     --(*this->_refCount);     if (this->_refCount == 0) {       delete _ptr;       delete _refCount;       _ptr = nullptr;       _refCount = nullptr;    &nsp;      }
    }
​
private:
    T* _ptr;
    int* _refCount; /* 所有指向该对象的指针指向同一个计数器 */
};

weak_ptr

weak_ptr 是一个不控制资源资源生命周期的智能指针,是对对象的一种弱引用,只提供了对其管理的资源的一个访问手段,引入它的目的是协助 shared_ptr 工作。

weak_ptr 可以从一个 shared_ptr 或另一个 weak_ptr 对象构造,shared_ptr 可以直接赋值给 weak_ptr,也可以通过 weak_ptr 的 lock 函数来获得 shared_ptr。

因为无论通过哪种方式来创建 weak_ptr,都不会增加资源的引用计数,所以当我们用 weak_ptr 来引用资源时,需要采用 expired 方法来检测引用的资源是否有效, 方法返回 true 说明其引用的资源已经失效,返回 false 说明该资源仍然有效。

标签: sp6t中等功率射频继电器

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台