Как я могу использовать трехмерные данные в качестве свойства класса? - PullRequest
1 голос
/ 15 сентября 2010

Прошло много времени с тех пор, как я работал с C ++, но у меня есть класс, который использует трехмерные данные, и я не могу понять, как я могу заставить эту работу работать.Мне нужно размеры размеров, которые будут определены в конструкторе.Я пробовал это в заголовке:

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

и это в конструкторе:

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

, но это возвращает ошибку: "объявление" значений "в качестве многомерного массива должно иметь границы длявсе измерения, кроме первого ".

Также использование этого в конструкторе не работает:

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

Я также пытался использовать вектор, но без особого успеха.Заголовок:

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

Ничего в конструкторе.Нет ошибок компилятора, но когда я пытаюсь установить значение:

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

, программа вылетает.

Кажется, что это так просто, но я просто не могу понять ...

Ответы [ 2 ]

3 голосов
/ 15 сентября 2010

Программа аварийно завершает работу при доступе к этому вектору, потому что он пуст, т. Е. Нет элементов с этими индексами.

Лучший способ сделать это - создать линейный одномерный вектордаже массив) и доступ к нему с помощью пары 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 голос
/ 15 сентября 2010

Просто чтобы понять, почему Кубби прав, это будет конструктор трехмерного вектора:

vector<vector&ltvector&ltfloat>>> 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; (используя new float[c][r][d]; в ctor), но это тоже ужасно.

...