Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/129.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;使用智能指针的合成_C++_Smart Pointers_Composition - Fatal编程技术网

C++ C++;使用智能指针的合成

C++ C++;使用智能指针的合成,c++,smart-pointers,composition,C++,Smart Pointers,Composition,我正在遵循游戏对象架构的设计。 简单地说,游戏对象类可以包含多个属性和行为子类实例。游戏对象也包含在场景类中。这张图可以澄清一些事情: 行为子类需要能够访问其父游戏对象类。这是必需的,因为行为需要能够读取和写入各种属性,并订阅以接收来自游戏对象的事件。某些行为可能还需要访问其父游戏对象的场景,以便可以实例化其他游戏对象 我目前正在使用共享指针和弱指针。例如,游戏对象类包含向量和向量。然后,行为类和属性类都包含一个弱\u ptr。这打破了参考循环 现在,如果行为想要访问场景,它需要执行一些嵌套的

我正在遵循游戏对象架构的设计。 简单地说,游戏对象类可以包含多个属性和行为子类实例。游戏对象也包含在场景类中。这张图可以澄清一些事情:

行为子类需要能够访问其父游戏对象类。这是必需的,因为行为需要能够读取和写入各种属性,并订阅以接收来自游戏对象的事件。某些行为可能还需要访问其父游戏对象的场景,以便可以实例化其他游戏对象

我目前正在使用共享指针和弱指针。例如,游戏对象类包含
向量
向量
。然后,行为类和属性类都包含一个
弱\u ptr
。这打破了参考循环

现在,如果行为想要访问场景,它需要执行一些嵌套的弱指针锁定:

if (std::shared_ptr<GameObject> sharedGameObject = GetGameObject().lock())
{
    if (std::shared_ptr<Scene> sharedScene = sharedGameObject->GetScene().lock())
    {
        // Do something with the scene.
    }
}
if(std::shared_ptr sharedGameObject=GetGameObject().lock())
{
如果(std::shared_ptr sharedScene=sharedGameObject->GetScene().lock())
{
//对场景做点什么。
}
}

这可能会有点混乱。如果我们需要访问应用程序类,那么需要3个嵌套锁。当使用原始指针时,这显然不是必需的。我是否使用了正确的智能指针?如果是的话,我能做些什么来整理这件事吗?或者这是我不得不忍受的事情吗?

我想你根本不需要任何智能指针,假设:

  • 游戏对象
    对象真正拥有
    属性
    行为
    对象,或
  • 游戏对象
    对象的生存期将始终长于
    属性
    行为
    对象的生存期
或者考虑您的代码示例,思考以下问题:
else
节会做什么?他们会被处死吗?我认为答案应该是:“他们只做故障/错误检测和报告”,以及“不,我不能想象会这样”


您应该切换到GAMObjult//Cuff>类,使用<代码> STD::RealthyOnWrpuls<代码>,如果您希望它稍微更现代C++,或原始指针,或原始引用。

< P>这里您真的想要智能指针吗?乍一看,, 基于设计层次结构(和名称):

  • 如果这是一个典型的层次结构,那么只有一个层次结构
    应用程序
    ,不会动态分配,但会 是
    main
    中的局部变量。所以永远不会有一个聪明的人 指向它的指针

  • 所有的
    场景
    都属于
    应用程序
    ,因此从设计上看很清楚 谁拥有什么。在这两种情况下,都是1对n的关系,这 意味着拥有对象中的指针需要处于 容器。您可以使用
    std::unique\u ptr
    ,但它不能 似乎真的有必要;事实上,这似乎有点令人困惑: 要删除对象,您不需要使用
    delete
    ,而是要从 集装箱。(另一方面,对于原始指针,您需要 必须将其删除并从容器中删除。它是 这主要取决于你,尽管我倾向于简单 原始指针的数量。)

  • 如果这些类代表了我认为它们的功能,
    GameObject
    作为外部事件的结果来来去去去。这是一个典型的例子 现有智能指针都不相关的情况。 我猜大部分的
    游戏对象都是由
    
    场景
    响应事件;有些可能是由其他人创建的
    GameObject
    。但一旦被创造出来,他们就可以管理自己的一生, 并且可能会被
    删除,在他们的事件中删除此
    
    处理程序。(当然,所有对其生命周期感兴趣的对象
    必须使用observer模式注册为观察员。
    但无论如何都会是这样。)

  • EventDispatcher
    无疑具有指向任何对象的指针 对事件感兴趣,但这些是用于导航的。他们应该 不是聪明的指针。这是每个人的责任 对象使用
    EventDispatcher
    从它感兴趣的事件来看 很明显,它会解除析构函数中的所有内容, 因为死物对任何事件都不感兴趣,但它 也会(可能)在其他时间注册和注销 还有

请注意,
弱ptr
的必要性通常是好的 指示引用计数指针不是解决方案
您正在寻找。

一个可能的解决方案:完全删除弱的\u ptr对象。理想情况下,行为和属性对象根本不需要访问游戏对象,但如果它们绝对必须访问,则将游戏对象指针(或引用)传递给它们,作为调用它们的方法的参数。为什么在这里使用智能指针。这似乎并没有必要,你们可以用共享指针循环来编码它,然后在你们想让对象消失的时候调用一个shutdown方法。在shutdown方法中,您可以重置共享指针以允许删除目标对象。在使用指针之前,您可能仍然需要测试它们,以确保它们没有被重置,但这样可以避免弱指针锁对性能的影响。用原始指针替换弱指针怎么样?只要你能保证行为和属性对象在游戏对象被销毁之前被销毁(例如,被游戏对象析构函数销毁),原始指针将始终可以安全使用。@Homar and?你有什么所有权需要关心吗?如果是的话,这是否显而易见?在这种情况下,您不需要智能指针。如果指针仅用于导航,则它们应为原始点