shared_ptr 最简单应用

共享智能指针示例

#include <cstdlib>
//多个 shared_ptr 指向同一个 内存块
//修改任何一个内存块,都是在修改多有的 shared_ptr
#include <iostream>
using namespace std;
#include <boost/shared_ptr.hpp>
using namespace boost;
#include <cassert>
class A
{
  shared_ptr<int> no_;
public:
  A(shared_ptr<int> p):no_(p){}
  void SetValue(int n){*no_ = n;}
  int GetValue()const{return *no_;}
};
class B
{
  shared_ptr<int> no_;
public:
  B(shared_ptr<int> p):no_(p){}
  void SetValue(int n){*no_ = n;}
  int GetValue()const{return *no_;}
};
void Do()
{
    shared_ptr<int> Temp(new int(10));
    A a(Temp);
    B b(Temp);
    cout<<"a 的值为 : "<<a.GetValue()<<endl;
    a.SetValue(20);
    cout<<"b 的值为 : "<<b.GetValue()<<endl;
    assert(b.GetValue() == 20);
}
int main(int argc, char *argv[])
{
    Do();
    system("PAUSE");
    return EXIT_SUCCESS;
}

<think>好的,我现在需要帮助用户理解如何简单模拟实现shared_ptr。首先,我得回忆一下shared_ptr的基本概念和功能。shared_ptr是C++中的智能指针,用于管理动态分配的内存,通过引用计数实现多个指针共享同一对象的所有权,当最后一个shared_ptr被销毁时,对象会被自动删除。 用户可能希望了解如何手动模拟这个机制,所以需要分解shared_ptr的关键组成部分。首先是引用计数,需要一个计数器来跟踪当前有多少个指针指向同一对象。其次是模板类,以支持不同类型的对象。此外,还需要考虑拷贝构造函数、赋值运算符、析构函数,以及如何管理引用计数的增加和减少。 接下来,我应该考虑如何实现这些部分。引用计数可以用一个动态分配的整数来实现,每个shared_ptr实例都持有该整数的指针。当拷贝构造或赋值时,引用计数递增;当析构或重置时,递减,并在计数为零时删除对象和计数器。 需要注意的是,线程安全问题,但用户可能只需要一个简单的实现,所以暂时可以忽略。此外,还要处理自赋值的情况,在赋值运算符中需要先检查是否是同一个对象,避免错误的释放。 然后,要设计模板类,比如命名为SharedPtr,包含指向对象的指针和指向引用计数的指针。构造函数需要接受原始指针,初始化引用计数为1。拷贝构造函数需要复制指针和引用计数,并递增计数。析构函数则递减计数,并在必要时释放资源。 可能还需要实现解引用操作符(*)和箭头操作符(->),以便用户像使用普通指针一样使用SharedPtr。另外,可以添加一个use_count()方法,让用户查看当前引用计数。 在编写示例代码时,要确保语法正确,比如在析构函数中正确使用delete和delete[],以及处理引用计数的更新。同时,要测试代码是否存在内存泄漏或悬空指针的问题。 用户可能对具体的实现步骤和代码结构感兴趣,所以需要分步骤解释,并提供代码示例。同时,要指出这个简单实现与标准库shared_ptr的区别,比如缺少自定义删除器、线程安全等,以帮助用户理解实际应用中的复杂性。 最后,确保回答结构清晰,逐步引导用户理解每个部分的作用,并强调注意事项和潜在的改进空间,这样用户就能掌握基本实现原理,并根据需要进一步扩展。</think>好的,我将分步骤为您解释如何简单模拟实现一个类似 `shared_ptr` 的智能指针,并附上代码示例和关键分析。 --- ### 实现原理 `shared_ptr` 的核心是 **引用计数** 机制: 1. 每个对象分配一个引用计数器 2. 拷贝时计数器+1 3. 析构时计数器-1 4. 当计数器归零时释放资源 --- ### 基础实现代码 ```cpp template <typename T> class SharedPtr { private: T* ptr; // 指向实际对象的指针 int* count; // 引用计数器(必须动态分配) public: // 构造函数 explicit SharedPtr(T* p = nullptr) : ptr(p), count(new int(1)) {} // 拷贝构造函数 SharedPtr(const SharedPtr& other) : ptr(other.ptr), count(other.count) { ++(*count); } // 赋值运算符 SharedPtr& operator=(const SharedPtr& other) { if (this != &other) { // 防止自赋值 // 减少原指针的引用 if (--(*count) == 0) { delete ptr; delete count; } // 复制新内容 ptr = other.ptr; count = other.count; ++(*count); } return *this; } // 析构函数 ~SharedPtr() { if (--(*count) == 0) { delete ptr; delete count; } } // 解引用操作符 T& operator*() const { return *ptr; } // 箭头操作符 T* operator->() const { return ptr; } // 获取引用计数 int use_count() const { return *count; } }; ``` --- ### 关键点解析 1. **引用计数器设计**: - 使用动态分配的 `int` 保证所有拷贝共享同一计数器 - 初始化时计数器设为1 2. **拷贝控制**: - 拷贝构造时复制指针并递增计数器 - 赋值运算符需处理自赋值,先减少原引用 3. **资源释放时机**: - 析构时递减计数器,当计数器归零时才释放资源 --- ### 使用示例 ```cpp class MyClass { public: MyClass() { std::cout << "Constructed\n"; } ~MyClass() { std::cout << "Destroyed\n"; } }; int main() { SharedPtr<MyClass> p1(new MyClass); // 计数器=1 { SharedPtr<MyClass> p2 = p1; // 计数器=2 std::cout << "Use count: " << p2.use_count() << "\n"; } // p2析构,计数器=1 SharedPtr<MyClass> p3; p3 = p1; // 计数器=2 } // p3,p1析构,计数器归零,对象销毁 ``` 输出结果: ``` Constructed Use count: 2 Destroyed ``` --- ### 与标准库差异 1. ❌ 缺少线程安全(标准库的引用计数是原子操作) 2. ❌ 不支持自定义删除器 3. ❌ 没有实现 `weak_ptr` 相关功能 4. ❌ 未处理循环引用问题 --- ### 改进方向 1. 使用原子操作保证线程安全 2. 添加模板参数支持自定义删除器 3. 实现 `make_shared` 优化内存布局 4. 添加 `weak_ptr` 支持 这个简化实现可以帮助理解智能指针的核心机制,实际开发中请直接使用标准库的 `std::shared_ptr`。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值