堆栈指向C ++中对象/对象的指针的内存分配

时间:2017-07-03 08:22:24

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

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

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

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对象的空间?

2 个答案:

答案 0 :(得分:5)

  

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

使用间接和动态分配几乎没有效率。当您存储的对象复制(例如写入时复制字符串)时,它的效率会更高。它也是"必需"当你想引用到同一个对象而不复制它时。

TL; DR:

  • 除非您有充分理由介绍间接,否则请选择
  • 首选引用指针,因为他们没有" null状态"。
  • 考虑TileType:它是enum,其大小很可能小于或等于sizeof(void*)。通过将其存储为指针并通过指针返回它,您什么​​也得不到并失去一切。

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

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

  

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

您似乎需要阅读一本好的C ++书籍并理解指针和参考的基础知识。除非你初始化你的指针,否则它们将具有垃圾值。

  1. 您不应该使用原始指针来拥有所有权。你应该使用智能指针。

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

答案 1 :(得分:0)

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

例如,我认为没有必要执行new,因为在构造函数中,您必须调用delete,然后在析构函数tileType中调用成员<% if(DisplayBtn == true) { %> <input type="image" src="/img/pencil.png" onClick="document.sentToBack.submit()" /> <% } %> 几乎没有空间,也不需要共享。

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