【问题标题】:Class Objects or Pointers to their Objects? Class object combination and Implementation类对象或指向其对象的指针?类对象组合与实现
【发布时间】:2013-03-27 06:41:52
【问题描述】:

问题背景

我正在开发一款类似战舰的基本衍生游戏,随着时间的推移,我想继续在 C++ 中添加功能(无图形)。目前我有一个 50 x 75 的游戏板,用 char 类型的 2D 矢量(称为 GameBoard)表示。我创建了一个游戏板并用“。”设置每个位置。字符。当您猜测坐标时,之前猜测的位置会标有“-”,而命中的位置会标有“X”


我在项目中的进展情况

我决定修改游戏以启用更多功能。我并没有走得太远,但是用伪代码勾勒出一个设计草图让我开始更多地思考如何进行这次升级。

GameBoard 不是字符,而是创建一个名为 Block 的类(棋盘上的一个空白区域),它现在将具有 ax 和 y 坐标变量, 以及一个 char 变量以直观地显示正确的字符。 Block 具有保存对象“Feature”的能力,该对象分解为“feature”的派生类。您可以滚动到最底部以了解有关这些类的更多详细信息。

这就是我的类层次结构树的走向:

                             feature 
                    item               vehicle
               gold     nuke                 plane

我需要什么帮助

我基本上有我想做的事情的大纲/结构设置。现在我只需要一些帮助来启动它来连接一切。我不太擅长确定何时以及如何使用指针。

A.) 我应该更改 GameBoard 以保存 Block 类的指针吗?还是实际的 Block 对象? - Block 会持有指向 Feature 或实际 Feature 对象的指针吗?

B.) 如何添加可以为空或给定值的 Feature 变量?我只是将其设置为 NULL 吗?

C.) 我是否需要自定义复制构造函数来交换 BlockFeature 值?

D.) 如果玩家使用了 Feature 对象,我该如何从 Block 中移除它?

E.) 一个Block偶尔可以有超过1个Feature吗?

F.) 如何声明 BlockFeature 类,以便 Block 可以容纳 Feature并且 Feature 已经派生自另一个类(未包含在本文中)。


关于我的课程的额外详情

所以 GameBoard 是存储块的向量。块本质上是板上的各个空间。块包含其位置的坐标、表示它的字符以及持有 Feature 对象的可能性,但大多数时候 Block 不会持有特征. Feature来源于Block,在游戏中作为奖励奖励。所以 Feature 分支成另外 2 个派生类,一个 Item Feature 或 Vehicle。以此类推。

当玩家选择坐标时,一个方法将转到 GameBoard 上/中的那个 Block,并首先检查 char 值是否代表一个之前没有使用过的有效空间。然后它检查这个块的内容以获得特征。 Feature 可能为空或包含派生的 Feature 对象。

好的,我的小说到此结束。抱歉写了这么多。我认为获得帮助的最佳方式是让帮助者知道发生了什么。请不要回应告诉我“直奔主题”。我知道我知道.. 如果我遗漏了细节,请告诉我。谢谢!

【问题讨论】:

    标签: c++ class object pointers inheritance


    【解决方案1】:
    1. 我不确定从类block 派生类feature 是否是个好主意
    2. 我宁愿在block 的每个实例中使用指向feature 的指针,这样如果没有特性,指针就是NULL在您的情况下,此指针将指向基类feature。我鼓励使用virtual 方法来访问各个功能。
    3. feature 用完时,删除它并将指向它的指针设置为NULL。 (块实例中的指针)
    4. 如果您希望每个 block 一次拥有多个 feature,请考虑使用某种数组/指针堆栈。
    5. 在我看来,GameBoard 应该包含 Blocks 的实际实例(而不是指针)。
    6. 我不明白你的意思:

    是否需要自定义复制构造函数来交换 Block 的 Feature 值?

    我希望这会有所帮助 =)。

    【讨论】:

      【解决方案2】:

      我认为您的 GameBoard 是 GameObject 指针的容器是个好主意。您不需要创建一个全新的类并将其命名为 Block - 所有这些都是隐含的。也不需要跟踪块的坐标,因为它们是按顺序排列的。 GameObject 将是游戏元素层次结构的基类 - 在您的情况下,这将是一个 Feature,我使用 GameObject 的原因是因为 Feature 描述性不是很好 - 这个术语太宽泛了。

      当游戏开始时,您的 GameBoard 可以由空指针填充,这些空指针随后被创建并添加到棋盘的实际游戏元素替换。

      如果您有动态分配的数据,您只需要实现复制构造函数和赋值运算符。如果没有,编译器将生成一个非常好的版本,可以进行原始对象复制。

      话虽如此,您最好不要移动实际的对象实例,而使用建议的使用指针的方法,您只会移动指针,这更简单、更快。

      如果你想删除一个Feature,只需删除实际对象并将其在board中的指针设置为null。

      如果您实现父/子关系,您可以在每个块中拥有一棵游戏对象树,您可以递归地遍历该树并按照您的意愿对树元素进行操作。

      设计良好的多态层次结构将允许您放置几乎任何东西,只要它是从您的基类派生的。

      【讨论】:

        【解决方案3】:

        我假设你想保持你的班级结构。在您的抽象点上,我建议通过(C++ 11 或 Boost)使用共享和 uniqe 指针。如果您不擅长指针,请了解 uniqe 和共享指针的工作原理并尝试坚持使用它们。请记住尽可能缩短对象的生命周期。

        A.) 我应该更改 GameBoard 以保存 Block 类的指针吗?还是实际的 Block 对象? Block 是否会持有指向 Feature 或实际 Feature 对象的指针?

        我想将此 GameBoard 元素保留为不可变的唯一指针或保留实际实例。

        B.) 如何添加可以为空或给定值的特征变量?我只是将其设置为 NULL 吗?

        您已决定将 Feature 保留在 Block 中 - 好的。如果是这样,请将其保留为共享指针。如果没有特征共享指针将为空。

        C.) 我是否需要自定义复制构造函数来交换 Block 的 Feature 值?

        仅当功能内部存在动态/不寻常的东西时。该功能将包含什么内容?

        D.) 如果玩家使用了 Feature 对象,我该如何从 Block 中移除它?

        如果你使用共享指针没有问题。即使在处理之前的 Feature 过程中 Feature 发生了变化,当 GameBoard 不再需要 Feature 时,Feature 也会被正确处理并销毁。

        E.) 一个 Block 上偶尔会出现超过 1 个 Feature 吗?

        您必须问自己这个问题 - 您的游戏是否需要处理这种情况?如果是这样,只需保存指向特征的共享指针的向量/映射/集合/数组(取决于您的要求)。

        F.) 我如何声明 Block 和 Feature 类,以便 Block 可以容纳一个 Feature 并且 Feature 已经派生自另一个类(不包括在这篇文章中)。

        我不确定我是否正确理解了这个问题:

        class Feature : public GameElement {
           /* Feature implementation */
        }
        
        class Block {
            shared_ptr<Feature> mFeature;  
            /* Block implementation */  
        };
        

        它回答了你的问题吗?

        【讨论】:

          猜你喜欢
          • 2023-02-09
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-12-20
          • 2011-10-01
          • 2021-05-20
          • 2011-02-11
          • 2014-01-26
          相关资源
          最近更新 更多