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

Pon*_*dle 6 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,因此它永远不会被自动销毁.

我相信这个解决方案是合理的,但它仍然感觉非常黑客.有没有更好的方法来解决我的问题?

Ant*_*nov 5

如果你想将非托管指针(你自己管理)传递给期望智能指针的代码shared_ptr,你可以通过创建空的但不是null的shared_ptr通过别名构造函数来禁用«smart»指针功能:

Texture* unmanagedPointer = ...
shared_ptr<Texture> smartPointer(shared_ptr<Texture>(), unmanagedPointer);
Run Code Online (Sandbox Code Playgroud)

由于没有控制块分配和引用计数正在进行,因此该解决方案比其他人建议的自定义删除器更有效且更短.

其他一些细节可以在这里找到:

C++中的空和空std :: shared_ptr有什么区别?

如何使用std :: make_shared避免大内存分配