gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:22:03 24 4
gpt4 key购买 nike

首先,我确实意识到这完全违背了 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/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com