boxmoe_header_banner_img

Hello! 欢迎来到悠悠畅享网!

文章导读

怎样实现自定义智能指针 引用计数模板开发指南


avatar
站长 2025年8月16日 3

实现自定义智能指针需通过模板和引用计数控制对象生命周期。首先定义RefCountBlock管理指针和引用计数,构造时初始化计数为1,析构时删除对象;再实现SharedPtr模板类,封装控制块指针和原始指针,拷贝时增加引用计数,赋值前处理自赋值并释放旧资源,析构时调用release递减计数,归零则删除控制块;为支持继承体系,添加跨类型构造函数,允许SharedPtr转为SharedPtr;测试示例验证构造、析构顺序及引用计数变化,确保无内存泄漏。最终实现一个基础的引用计数型智能指针。

怎样实现自定义智能指针 引用计数模板开发指南

实现自定义智能指针并加入引用计数机制,核心在于管理对象生命周期,避免内存泄漏和重复释放。通过模板技术,可以让智能指针支持任意类型,提升通用性。下面详细介绍如何一步步开发一个简单的引用计数型智能指针模板。

设计引用计数控制块

为了实现共享所有权,需要一个独立的控制块来保存引用计数和指向实际对象的指针。这个控制块由所有指向同一对象的智能指针共享。

控制块通常包含:

  • 指向管理对象的指针
  • 当前强引用的数量(决定对象何时释放)
  • 析构时清理资源的逻辑

示例代码结构:

template<typename T> class RefCountBlock { public:     T* ptr;     int ref_count; <pre class="brush:php;toolbar:false"><pre class="brush:php;toolbar:false">RefCountBlock(T* p) : ptr(p), ref_count(1) {} ~RefCountBlock() { delete ptr; }

};

实现智能指针模板类

定义一个模板类 SharedPtr,封装对控制块和对象的访问。构造、拷贝、赋值和析构操作都需要更新引用计数。

关键操作包括:

  • 构造时创建控制块或绑定已有块
  • 拷贝构造时增加引用计数
  • 赋值操作需处理自赋值和旧资源释放
  • 析构时减少计数,归零则删除对象

基本框架:

template<typename T> class SharedPtr { private:     T* ptr;     RefCountBlock<T>* block; <pre class="brush:php;toolbar:false"><pre class="brush:php;toolbar:false">void release() {     if (block && --block->ref_count == 0) {         delete block;     }     ptr = nullptr;     block = nullptr; }

public: explicit SharedPtr(T* p = nullptr) : ptr(p), block(p ? new RefCountBlock(p) : nullptr) {}

SharedPtr(const SharedPtr& other) : ptr(other.ptr), block(other.block) {     if (block) ++block->ref_count; }  SharedPtr& operator=(const SharedPtr& other) {     if (this != &other) {         release();         ptr = other.ptr;         block = other.block;         if (block) ++block->ref_count;     }     return *this; }  ~SharedPtr() {     release(); }  T& operator*() const { return *ptr; } T* operator->() const { return ptr; } int use_count() const { return block ? block->ref_count : 0; } explicit operator bool() const { return ptr != nullptr; }

};

支持模板类型推导与赋值兼容性

为了让智能指针支持继承关系的指针赋值(如子类转父类),需要添加模板构造和赋值函数。

例如,允许 SharedPtr 赋值给 SharedPtr

添加泛化构造函数:

template<typename U> SharedPtr(const SharedPtr<U>& other) : ptr(other.ptr), block(other.block) {     if (block) ++block->ref_count; } 

注意:需确保类型转换安全,可通过 static_castdynamic_cast 控制转换逻辑。

测试与使用示例

验证智能指针是否正确管理生命周期。

#include <iostream> struct Test {     Test() { std::cout << "Test()n"; }     ~Test() { std::cout << "~Test()n"; } }; <p>int main() { { SharedPtr<Test> p1(new Test); std::cout << "ref count: " << p1.use_count() << "n";</p><pre class="brush:php;toolbar:false"><pre class="brush:php;toolbar:false">    {         SharedPtr<Test> p2 = p1;         std::cout << "ref count: " << p1.use_count() << "n";     }      std::cout << "p2 out of scopen"; } // p1 析构,对象释放 return 0;

}

输出应显示构造一次、析构一次,引用计数正确增减。

基本上就这些。通过封装控制块和正确管理引用计数,就能实现一个基础但实用的引用计数智能指针模板。后续可扩展支持弱引用、自定义删除器等功能。



评论(已关闭)

评论已关闭