C++ 类中的所有数组都必须动态分配,还是只是它们的成员变量?

问题描述

对于一项作业,我不得不将 Conway's Game of Life 的一些代码分成多个文件,但现在我试图更深入地了解为什么代码是这样编写的。我有一个World,该类的构造函数的一部分如下所示:

world.h:

class World {
public:
    // Constructor/destructor
    World();
    ~World();
    
    void updateWorld();

    ...

private:    
    char **m_grid_1;
    char **m_grid_2;

    ...
};

world.cpp:

World::World()
{
    m_toggle = true;

    m_grid_1 = new char*[MAX_ROWS];
    m_grid_2 = new char*[MAX_ROWS];

    for (int i = 0; i < MAX_ROWS; i++) {
        m_grid_1[i] = new char[MAX_COLS];
        m_grid_2[i] = new char[MAX_COLS];
    }

    ...
}

MAX_ROWSMAX_COLS 是现在存在于标题中的全局变量

数组总是让我有点困惑,所以这些问题可能看起来有点基本:

  1. char** 在成员变量 m_grid_1m_grid_2 的上下文中是什么意思?指向 char 的指针的指针?这些成员是二维数组,所以我不确定为什么在这里使用指针。

  2. 为什么 new 在这里与构造函数中的循环结合使用?你不能直接说m_grid_1[MAX_ROWS][MAX_COLS];吗?

此外,如果我想在成员函数 m_grid_1 中制作 updateWorld() 的本地副本并使用该本地副本获取游戏的下一个状态,而不是在两个网格之间切换,我需要使用new吗?这就是我现在所拥有的,它似乎有效,但我不确定我是否因为没有在此处动态分配二维数组而做错了什么:

void World::updateWorld() {
    char grid_copy[MAX_ROWS][MAX_COLS];

    for (int i = 0; i < MAX_ROWS; i++) {
        for (int j = 0; j < MAX_COLS; j++) {
            grid_copy[i][j] = m_grid_1[i][j];
        }
    }
  
  // loop over grid_copy to find next state of m_grid_1
  
}

解决方法

C++ 类中的所有数组都必须动态分配吗?

一般不会。

或者只是他们的成员变量?

成员变量也不必动态分配。

  1. char** 是什么意思...指向字符指针的指针?

它是一个指向 char 的指针。

那些成员是二维数组

更正:这些成员是指针。它们使用了指针,因此它们不是数组。

  1. 为什么在此处将 new 与构造函数中的循环结合使用?

因为程序的作者选择使用它。

你不能直接说 m_grid_1[MAX_ROWS][MAX_COLS]; 吗?

也许吧。如果 dependencies { "lib1","lib2" } lib1 dependes on lib3:6.*.* lib2 depends on lib3:9.*.* MAX_ROWS 是编译时间常数并且它们很小,那么肯定。

如果我想在成员函数 updateWorld() 中制作 m_grid_1 的本地副本并使用该本地副本来获取游戏的下一个状态,我是否需要使用 new?

如果问题是你是否需要动态分配,那么也许吧。请参阅上面的答案。

几乎不需要使用MAX_COLS。创建动态数组的一种更简单、更安全的方法是使用 new