C++ 多维数组成员访问器

C++ multidimensional array member accessor

我有一个 class,里面有一个大的二维数组。它曾经是一个分配在堆上的动态数组,现在它是我更喜欢的静态大小。

private:
    int fontTextureCoords_[100][7];

我必须将类型转换添加到访问器,以便 return 数组在 class 之外访问,目前工作正常,但我不确定它是否安全或者正确的处理方式。

public:
inline int **getFontTextureCoords()
{   
    return (int**)fontTextureCoords_;
}

这样做安全/正确吗?还是有更好的方法 return指向多维数组的指针?

int fontTextureCoords_[100][7]; 之类的数组转换为 int** 是不正确的。它会导致未定义的行为。

如果不是太多,把getFontTextureCoords改成:

inline int (*getFontTextureCoords()) [7]
{   
    return fontTextureCoords_;
}

并将其用作:

int (*ptr)[7] = getFontTextureCoords();

如果您可以选择使用std::vectorstd::array,最好使用它们。

不是正确的方法,不应编译。二维数组不能转换为指向指针的指针。您必须 return 一个指向数组的指针,使用 typedef 最容易编写:

using T = int[7];
inline T* getFontTextureCoords() { return fontTextureCoords_; }

尽管仅 return 引用整个数组会好得多:

using T = int[100][7];
inline T& getFontTextureCoords() { return fontTextureCoords_; }

你也可以 std::array<std::array<int, 7>, 100>

C/C++中没有多维数组。只有一维数组。你可以有一个一维数组,它的每个元素都是另一个一维数组。虽然看起来没有什么区别,但它是存在的,而且非常重要。

这正是传递逻辑不起作用的方式。每个人都经历过。 'If single-dimensional arrays are passed as a pointer to the first elelement, 2-D arrays should be passed as a pointer to pointer to first element, etc'。但由于它不是二维数组,而是数组的数组,所以无法应用该逻辑。

您可以通过以下方式进行推理。比方说,你有一个类型为 X 的数组。

X x[10];

如何访问第 5 个元素?简单 -

x[5] = 42;

但是编译器在看到它时会做什么?它大致是这样的:

*(&x[0] + 5) = 42;

所以它获取第一个元素的地址,并将其加 5 以获得第 5 个元素的地址。但是加 5 意味着什么呢?以字节为单位,应从数组开头的地址跳过多少字节才能到达请求的内存位置?当然是 5 * sizeof(X)。现在,如果你有“二维”数组,声明如下:

X x[2][3];

并且您尝试通过指向指针的指针来使用它:

px = (X**)x;
px[3][4] = 42;

记住,为了生成[][]的代码,编译器需要用*(px + )的方式表达。并且必须是数组的大小(因为数组的元素是数组)。但是为此您需要知道数组大小,正如您所见,您的 px 中没有编码任何数组大小。它知道的唯一大小是 X 的大小,这还不够。

希望它有意义,并解释了为什么不能使用 int** 而不是 x[][]。

也许这张图向您展示了两种多维数组声明之间的区别。 (有时人们不理解这一点。)

第一个说 a 是一个由 100 个连续的 7-int 块组成的块,或者总共 700 ints 个块,所有块都在一起。

第二个说 a 是一个指针数组,其中每个指针指向 ints 的不同块,分散在内存中。

编译器需要知道这一点,因为如果你写 a[i][j] 它必须生成完全不同的代码。