随笔 - 576  文章 - 0  评论 - 62  阅读 - 219万

理解shared_ptr<T> ---2

1、引用计数字段不能放在资源管理类中。我们的解决办法是,把引用计数和资源绑在一起,进行二次封装。但是这样存在一个大问题,不同类型的资源管理类不能兼容。也就是说,shared_ptr<Dog>不能赋值给shared_ptr<Animal>。

2、你可能会想,使用模版成员方法去解决,但是这里有个问题。因为进行了两次封装,u_ptr的类型还是不一样,也不能赋值。你可能会想,我在u_ptr中也建立模版成员方法,这也是错的。思考下,我们要保证,资源管理类指向同一个u_ptr,对u_ptr进行拷贝,那么资源管理类就不是指向同一个u_ptr了,这显然是错的。

3、有没有其它的办法呢?

  问题的关键是,进行了两次封装。不进行两次封装就好了,为了保证资源管理类指向同一个资源,同时指向同一个引用计数值,我可以再建立一个int指针,指向引用计数。

4、示例代码:

复制代码
 1 template <typename T>
 2 class shared_ptr_2
 3 {
 4 public:
 5  shared_ptr_2(T* ptr):_ptr(ptr),_refCount_ptr(new int(1))
 6  {
 7  }
 8 
 9  shared_ptr_2(shared_ptr_2<T>& rhs)
10  {
11   _ptr= rhs._ptr;
12   _refCount_ptr = rhs._refCount_ptr;
13   ++(*_refCount_ptr);
14  }
15 
16  template <typename U>
17  shared_ptr_2<T>(shared_ptr_2<U>& rhs)
18  {
19   _ptr = rhs._ptr;
20   _refCount_ptr = rhs._refCount_ptr;
21   ++(*_refCount_ptr);
22  }
23 
24  shared_ptr_2& operator=(shared_ptr_2<T>& rhs)
25  {
26   if(this!=&rhs)
27   {
28    if(--(*_refCount_ptr) ==0)
29    {
30     delete _ptr;
31     delete _refCount_ptr;
32    }
33    _ptr= rhs._ptr;
34    _refCount_ptr = rhs._refCount_ptr;
35    ++(*_refCount_ptr);
36   }
37   return *this;
38  }
39 
40  template <typename U>
41  shared_ptr_2<T>& operator=(shared_ptr_2<U>& rhs)
42  {
43   ++(*_refCount_ptr);
44   if(--(*_refCount_ptr) ==0)
45   {
46    delete _ptr;
47    delete _refCount_ptr;
48   }
49   _ptr= rhs._ptr;
50   _refCount_ptr = rhs._refCount_ptr;
51   return *this;
52  }
53 
54  ~shared_ptr_2()
55  {
56   if(--(*_refCount_ptr) ==0)
57   {
58    delete _ptr;
59    delete _refCount_ptr;
60   }
61  }
62 
63 private:
64  T* _ptr;
65  int* _refCount_ptr;
66 
67  friend class shared_ptr_2;
68 };
复制代码

 

posted on   Andy Niu  阅读(835)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
历史上的今天:
2012-01-17 C# 值类型 与 引用类型
2012-01-17 .net 应用程序执行过程
2012-01-17 自包含 与 自描述
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示