共享通过智能指针拥有的对象
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_Components在 Game 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.
基本上我有一个结构,其中包含要在 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_Components在 Game 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.