【问题标题】:Heap memory allocation for pointers to object/objects in C++C++中指向对象/对象的指针的堆内存分配
【发布时间】:2017-12-06 10:37:36
【问题描述】:

我读了一本关于游戏编程模式的书,并决定在我不上课的时候写一个小引擎来娱乐/练习,这会大量使用对象指针。

我创建了一个Tile 类来表示地图的一个区域(位于标准的 2D 坐标平面上,它是指向 Tile 对象的指针的 2D 数组),其中包含其他类型的对象(臭名昭著的瓷砖陷阱,一个字符和一个地面类型),如下所示,其中包含指向 tile 对象将保存的数据的指针。

class Tile
{
public:
    enum TileType{
        WATER_DEEP,
        WATER_SHALLOW,
        GRASS,
        MUD
    };

    Trap* getTileTrap();
    GameObject* getTileObject();
    TileType* getTileType();

    Trap *tileTrap;
    GameObject *tileObject;
    TileType *tileType;

    Tile();
    virtual ~Tile();

protected:
private:
};

我很好奇的是它是否更高效,内存/性能明智,保持它的编写方式,让这个 tile 对象(在堆上分配)包含指向其他对象的指针,或者我应该废弃指针并简单地返回对象?

如果我保留它的编写方式,指针指向的对象是在堆上的其他地方创建的吗?它们会被随机分配到某个地方,还是将它们与创建时分配给 Tile 对象的空间一起分配?

【问题讨论】:

  • 这与其说是效率考虑,不如说是设计问题。你的对象有身份和可变状态吗?在这种情况下,您不能简单地“返回对象”,因为生成的副本将是不同的对象。
  • 使用智能指针

标签: c++ memory-management heap-memory


【解决方案1】:

在内存/性能方面更有效,保持它的写入方式,让这个 tile 对象(在堆上分配)包含指向其他对象的指针,或者我应该废弃指针并简单地返回对象?

使用间接和动态分配几乎从未如此有效。只有当您存储的对象的复制成本很高时,它才会更有效(例如,写时复制字符串)。当您想要引用同一个对象而不复制它时,它也是“必需的”。

tl;博士:

  • 首选,除非您有充分的理由引入间接
  • 引用优于指针,因为它们没有“空状态”。

  • 考虑TileType:这是一个enum,其大小很可能小于或等于sizeof(void*)。通过将其存储为指针并通过指针返回它,您将一无所获并失去一切。

    如果您通过指针存储它,这意味着您可能需要动态分配。每次访问时都需要跳过一个指针。

  • 关于TrapGameObject:取决于它们的大小以及是否需要引用语义,您可能需要使用std::unique_ptrstd::shared_ptr 来存储它们,并返回 Trap&/GameObject& 以允许访问。


如果我保留它的编写方式,指针指向的对象是在堆上的其他地方创建的吗?它们会被随机分配到某个地方,还是将它们与创建时分配给 Tile 对象的空间一起分配?

看来您需要阅读一本好的 C++ 书籍并了解指针和引用的基础知识。除非您初始化指针,否则它们将具有垃圾值。

  1. 您不应使用原始指针作为所有权。您应该使用智能指针。

  2. 除非有充分的理由,否则不应使用动态分配。

【讨论】:

    【解决方案2】:

    当您希望使用创建它的函数或可以“共享”的存储不会过期时,该指针很有用。您可以将它们视为某种全局变量,只要您没有忘记指针或没有释放内存,它就可以访问。例如,您可以让一个Tile 对象创建GameObject,而另一个Tile 类型的对象共享指向同一GameObject 的指针。但是指针不是对象,这意味着对于Tile 类,您需要分配堆上的所有成员,然后在适当的时候手动释放它们。

    例如,我认为TileType* getTileType(); 没有意义,因为在构造函数中,您必须调用new,然后在析构函数中调用delete 的成员tileType,它几乎不占用空间,并且不是需要共享。

    您应该熟悉指针是什么以及它有什么用处,它有它的用途,但也有它的局限性。一旦您意识到持有指针而不是变量的潜力,您将能够快速判断使用哪个,包括潜在的性能增益/惩罚。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-07-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-07
      • 1970-01-01
      相关资源
      最近更新 更多