2014-10-27 53 views
2

所以我已经超载运算符()为2d数组类。对于我正在做的随机测试,返回设置为array[0][index]。现在只传递列设置为0的索引(行)。如果索引小于行(那么我们在下一行),它仍然返回数据,就像我指定了列一样?C++二维数组索引与1参数(为什么这个工作?)

基本代码示例:

class myArr 
{ 
private: 
    float array[3][3]; 
public: 
    myArr::myArr(float a1, float a2, ...) { array[0][0] = a1; array[0][1] = a2; ... } 
    //^the "..." just means, the same action till float a9/array[2][2] = a9; 
    float& operator() (unsigned index) { return array[0][index]; } 
    const float operator() (unsigned index) const { return array[0][index]; } 
}; 

int main() 
{ 
    myArr test(1, 2, 3, 4, 5, 6, 7, 8, 9); 
    std::cout << myArr(4) << std::endl; // Displays 5 
    myArr(4) = 0; // Set's element 4 to hold value 0 
    return 0; 
} 

奇怪的是这个作品。我可以用1个参数设置/获取第5个元素。现在我想知道为什么/如何确切地起作用,当然它应该错误地出现“越界”或什么。最后这是“安全”还是强烈建议不要这样做?

我很少使用2D阵列,这主要是由于它们缺乏性能增益。

回答

6

数组连续存储在内存中。在C++中,多维数组在内存中逐行存储,所以我相信这是一个非常有效的内存,可以超越当前行进入下一行。如果您超出了二维阵列的最后一行,则会出现超出范围的情况。

是否这是一件好事情是一个不同的问题。很明显,用这种方式编写代码会导致读者挠脑袋,试图弄清楚你在做什么,所以你想避免用这种方式编写真正的代码。

如果你声明一个二维数组,那么你会希望在数组的整个生命周期中保持这些语义,所以我强烈建议不要这样做。

+0

啊,这是有道理的。嗯,我会避免这一点,谢谢你。 – SharkBytes 2014-10-27 19:59:24

+1

@ user3046336在极端优化的情况下,执行1D访问可能会更快,而不是2D。除了这种情况,你的结论是避免它。 – 2014-10-27 20:03:44

+0

这是值得商榷的,它是否会导致未定义的行为通过像这样的数组末尾访问(虽然我现在找不到相关的线程) – 2014-10-27 20:23:05

0

当您分配2d数组时,其内存是连续的。所以如果你分配一个3 * 3的浮点数组,你将分配9 * 4个连续的字节。 结果是:

&array[0][i] = array + 0*3 + i = array + i = array[i] 

所以“偶然”,你会得到正确的结果。

+0

更具体地说,您分配九个数组元素,每个元素占用四个字节例如,假设sizeof(float)== 4。 – jia103 2014-10-27 19:53:12