如何将三维数据用作类属性?

时间:2010-09-15 12:09:14

标签: c++ arrays class initialization multidimensional-array

自从我使用C ++以来已经很长时间了,但是我有一个使用三维数据的类,我无法弄清楚如何使这个工作。我需要在构造函数中定义维度的大小。我在标题中尝试了这个:

class CImage
{
public:
    float values[][][];
...
}

,这在构造函数中:

CImage::CImage(int cols, int rows, int depth)
{
    values[cols][rows][depth];
}

但是这会返回错误:“作为多维数组的'values'的声明必须包含除第一个之外的所有维度的边界。”

在构造函数中使用它也不起作用:

values = new float[cols][rows][depth];

我也尝试使用矢量,但没有太大的成功。部首:

vector<vector<vector<float> > > values;

构造函数中没有任何内容。没有编译器错误,但是当我尝试设置一个值时:

values[c][r][d] = value;
程序崩溃了。

看起来很基本,但我无法理解......

2 个答案:

答案 0 :(得分:3)

程序在访问该向量时崩溃,因为它是空的,即这些索引中没有元素。

最好的方法是制作一个线性的,一维的矢量(甚至数组),并使用一对operator()来访问它,详情请见C++FAQ Lite。或者使用boost::multi_array

例如:

#include <vector>
#include <iostream>
class CImage
{
        int X, Y, Z;
        std::vector<float> values;
public:
        CImage(int cols, int rows, int depth)
                : X(cols), Y(rows), Z(depth),
                values(cols*rows*depth) {}
        float operator()(int x, int y, int z) const
        {
                return values[Z*Y*x + Z*y + z];
                // or you lay it out differently in memory
                // if you please, transparent to the user:
                // return values[x + X*y + X*Y*z];
        }
        float& operator()(int x, int y, int z)
        {
                return values[Z*Y*x + Z*y + z];
                // likewise, in a different layout
                // return values[x + X*y + X*Y*z];
        }
};

int main()
{
        CImage ci(3,3,3);
        ci(2,2,2) = 7.0;
        std::cout << ci(2,2,2) << '\n';
}

答案 1 :(得分:1)

为了说明为什么Cubbi是对的,这将是3d-vector的构造函数:

vector<vector<vector<float>>> values;
// create vector [dim0][dim1][dim2]
// init value: init
size_t dim0 = 3;
size_t dim1 = 3;
size_t dim2 = 3;
float init = 0.42f;
values = vector<vector<vector<float>>>
         (
            dim0,
            vector<vector<float>>
            (
                dim1,
                vector<float>
                (
                    dim0,
                    init
                )
            )
         );

很好,不是吗?

此外,你不能声明float values[][][];因为数组驻留在堆栈上,所以编译器必须在编译时知道该数组的大小(例外:C99可变长度数组,但这不会是C ++)。您可以声明float*** values;(在ctor中使用new float[c][r][d];),但这也很糟糕。