c++ - 将对象传递给期望 shared_ptr 的函数而不实际共享所有权

标签 c++ memory-management shared-ptr

首先,我确实意识到这完全违背了 shared_ptr 的目的。我正在处理一些库代码,其中 ParticleSystem 的实例希望在构造期间将 shared_ptr 传递给它们以设置用于每个粒子的纹理。问题是,我已经以我的纹理具有具体所有权(如果这是正确的术语)的方式构建了我的程序的其余部分 - TextureCache 拥有所有纹理。所以我需要一种方法来使用这个 ParticleSystem 类,而不允许它删除我的纹理。如果我只是创建一个像 ParticleSystem(std::shared_ptr<Texture>&myTexture) 这样的新实例然后它会在纹理被破坏时尝试破坏它(这是一个不需要的和无效的操作,因为我的纹理甚至不是用 new 创建的)。

我看到解决这个问题的最干净的方法是这样的:

  1. 在创建 ParticleSystem 的函数中创建一个保存纹理的 shared_ptr。
  2. 然后使用 placement new 在与我刚创建的 shared_ptr 相同的内存位置重建 shared_ptr。纹理现在的引用计数为 2。
  3. 创建粒子系统。
  4. 让 shared_ptr 超出范围。它的解构函数将被调用,因为它是在堆栈上分配的,它只会将引用计数减 1。因此,该对象的引用计数将始终比实际值大 1,因此它永远不会被自动销毁。

我相信这个解决方案是合理的,但它仍然令人难以置信的骇人听闻。有没有更好的方法来解决我的问题?

最佳答案

如果您想将非托管指针(您自己管理的)传递给需要智能指针的代码,例如 shared_ptr,您可以通过创建空的但非空的来禁用“智能”指针功能shared_ptr 通过别名构造函数:

Texture* unmanagedPointer = ...
shared_ptr<Texture> smartPointer(shared_ptr<Texture>(), unmanagedPointer);

这个解决方案比其他人建议的自定义删除器更高效、更短,因为没有控制 block 分配和引用计数正在进行。

一些额外的细节可以在这里找到:

What is the difference between an empty and a null std::shared_ptr in C++?

How to avoid big memory allocation with std::make_shared

关于c++ - 将对象传递给期望 shared_ptr 的函数而不实际共享所有权,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12127758/

相关文章:

c++ - 智能指针和复制构造函数

c++ - 弄清楚网络、十六进制和 ascii 如何交互

c++ - Microsoft 是否为其 CRT 版本提供 .obj 文件以在 CRT 代码路径上启用整个程序优化?

c++ - 如何将数据从资源指针存储到 C++ 中的静态内存缓冲区?

c++ - 在 C++ 中有效使用堆栈与堆内存分配

c++ - shared_ptr 构造函数的异常安全

c++ - 共享指针线程安全是零成本吗?

c++ - 如何对可变参数模板函数的异构参数包进行通用计算?

c++ - 不允许在同一个类中直接访问成员变量

iphone - 在 Instruments 中进行分析时 main.m 中的内存泄漏?