构造函数中的 C++ 二维数据数组 - 何时初始化和删除?

C++ 2D data array in constructor - When to initialize and delete?

这个问题可能有点愚蠢,但我对 C++ 还是个新手,我已经有一段时间没用它做了什么了。

我有一个名为 LEDBitmap 的 class,它应该保存位图的宽度、高度和数据,只有 1 和 0。

在头文件中我有以下结构:

struct MapData
{
  uint8_t width;
  uint8_t height;
  uint8_t[][] data;
};

以及下面的构造函数、析构函数和成员变量:

class LEDBitmap
{

  public:
    LEDBitmap(uint8_t width, uint8_t, height, uint8_t data[][]);
    LEDBitmap(uint8_t width, uint8_t, height);
    virtual ~LEDBitmap() {   };

  [...]

  private: //members
    MapData _map;
};

我现在想编写构造函数,可能还有析构函数,到目前为止,第一个构造函数如下:

//initialize an empty bitmap with only zeros in it
LEDBitmap::LEDBitmap(uint8_t width, uint8_t, height) {
  _map.width = width;
  _map.height = height;
  _map.data = new uint8_t[width][height];
}

这个实现可行吗? (可能不会) 我应该费心去实际实现析构函数吗?

编辑: 根据@gsamaras 的建议调整了我的代码。 _map以前是*_ptr

编辑: 一位朋友建议改用 calloc()。因此我现在有:

LEDBitmap::LEDBitmap(uint8_t width, uint8_t height) {
  _map.width = width;
  _map.height = height;
  _map.data = calloc(width*height*(sizeof(uint8_t));
}

class LEDBitmap
{

  public:
    LEDBitmap(uint8_t width, uint8_t, height, uint8_t data[][]);
    LEDBitmap(uint8_t width, uint8_t, height);
    virtual ~LEDBitmap() {
      free(_map.data);
    };

  private: //members
    MapData _map;

};

因为ptr是一个指针,所以不是。您正在尝试填充结构的字段,该结构甚至没有分配内存。这会导致 未定义的行为

  1. 你应该先为结构分配内存,然后填充 它。
  2. 然后,在析构函数中,您必须取消分配该内存。

记住,当使用 new 时,也必须使用 delete。通常,您希望调用 delete 的次数与调用 new 的次数完全相同。


但是为什么要用指针呢?在那种情况下,这似乎是多余的。当你没有充分理由使用指针时,你的代码容易出错。

您可以从以下建议中选择一些建议,而不是使用指针(不需要您定义构造函数):

  • 使用 std::vector<uint8_t> 完成所有后台工作 (related), 正如 NathanOliver 所说。
  • 使用struct MapData作为数据成员而不是指针。那 如果您希望重用该结构,则在 OOP 编程中有意义 例如,另一个 class。
  • 如果该结构仅用于此 class,则考虑 直接给 class 结构的字段,作为它的数据 成员,而不是结构本身。