共享通过智能指针拥有的对象

Sharing objects owned via smart pointer

基本上我有一个结构,其中包含要在 class 之间共享的对象,如下所示;

struct CoreComponents
{
    std::unique_ptr<a> m_A = std::make_unique<a>();
    std::unique_ptr<b> m_B;
    std::unique_ptr<c> m_C = std::make_unique<c>();
};

在我的主要 class 中,我通过 unique_ptr;

拥有它
class Game
{
    ...
  private:
    std::unique_ptr<CoreComponents> m_Components;
    ...
};

然后我还有其他 n classes 我需要访问 m_Components 对象,而不创建副本。 (我不会修改那个对象的内容)

我尝试使用 shared_ptr 来保持 m_ComponentsGame class 然后通过值将其传递给其他 classes(给他们的构造函数)并存储它但是场景导致内存泄漏。 (我使用 memcheck 来检查泄漏)我发现它是泄漏的原因,但我无法弄清楚为什么。

Shared_ptr场景

class 的构造函数,我需要访问 CoreComponents 对象;

GameScene::GameScene(std::shared_ptr<CoreComponents> components)
: m_Components(std::move(components))

我试图将其保留为 GameScene 的成员class,然后在函数中使用它;

std::shared_ptr<CoreComponents> m_Components;

这就是我从游戏内部传递它的方式 class;

auto gs = std::make_unique<GameScene>(m_Components)

GameScene 中的一般用法class;

m_Components->m_A->draw(*m_OtherObjectInsideGameScene);

那么使用现代 C++ 创建类似设计的最佳方法是什么? 我试图避免单例模式,但我是否必须使用它来实现这一点,或者可以更好地使用智能指针?

PS: 当游戏 class 被销毁时,CoreComponents 结构需要从内存中删除。

如果您有共享对象,最好的方法确实是使用 shared_ptr

A unique_ptr 用于唯一所有权。

如果您有内存泄漏,是时候调查原因并修复它们了!您的报告建议使用周期性参考。检查意外的 lambda 捕获,在某些地方您可能打算使用 weak_ptr

为此使用单例就像通过放火烧毁汽车的破轮胎来代替驴子一样。您的 unique_ptr 方法更像是通过拆下轮胎并在轮辋上行驶来修理汽车的破轮胎。

看来您正确区分了所有权使用 的关注点。您唯一的麻烦是如何将组件转发到系统的其余部分。

我会保留您拥有的结构,并为特定用户创建专用结构:

struct CoreComponents {
   unique_ptr<A> a; unique_ptr<B> b; ...
};

struct PartOfTheSystem {
  void use(A& a, B& b);
};

struct Game {
  CoreComponents components;
  PartOfTheSystem user;

  void stuff() {
    user.use(*components.a, *components.b);
  }
};

是:打字更多。

而且:非常清晰的逻辑:construction/ownership 和 use 是不同的关注点,这在设计上是非常清楚的!另请参阅 https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines#Rr-smartptrparam.