开发者

How can I use 3-dimensional data as a class property?

It's been a long time since I worked with C++, but I have a class that uses 3-dimensional data and I can't figure out how I can make this work. I need the sizes of the dimensions to be defined in the constructor. I tried this in the header:

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

and this in the constructor:

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

but this returns the error: "declaration of `values' as multidimensional array must have bounds for all dimensions except the first".

Also using this in the constructor does not work:

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

I also tried using vector, but without much success. Header:

vector<vector<vector<flo开发者_开发百科at> > > values;

Nothing in constructor. No compiler errors, but when I try to set a value:

values[c][r][d] = value;

the program crashes.

It seems so basic, but I just can't figure it out...


The program crashes when accessing that vector because it is empty, i.e. there are no elements at those indexes.

The best way to go about this is to make a linear, one-dimensional, vector (or even an array), and access it with a pair of operator()'s, see C++FAQ Lite for details. Or use boost::multi_array.

For example:

#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';
}


Just to poiny out why Cubbi is right, this would be the constructor of the 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
                )
            )
         );

Nice, isn't it?

Besides, you cannot declare a float values[][][]; because arrays reside on the stack, so the compiler has to know at compile time what size that array has (exception to this: C99 variable length arrays, but this would'nt be C++). You could declare a float*** values; (using new float[c][r][d]; in the ctor), but this is awful, too.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜