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:
自从我使用C ++以来已经很长时间了,但是我有一个使用三维数据的类,我无法弄清楚如何使这个工作。我需要在构造函数中定义尺寸的大小。我在标题中尝试了这个:
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".
但这会返回错误:“作为多维数组的'values'声明必须具有除第一个之外的所有维度的边界”。
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<float> > > 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...
这看起来很基本,但我无法弄明白......
2 个解决方案
#1
3
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.
最好的方法是创建一个线性的,一维的向量(甚至数组),并使用一对operator()访问它,有关详细信息,请参阅C ++ FAQ Lite。或者使用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';
}
#2
1
Just to poiny out why Cubbi is right, this would be the constructor of the 3d-vector:
只是为了说明为什么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
)
)
);
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.
此外,你不能声明浮点值[] [] [];因为数组驻留在堆栈上,所以编译器必须在编译时知道该数组的大小(例外:C99可变长度数组,但这不是C ++)。你可以声明一个浮动***值; (使用新浮点[c] [r] [d];在ctor中),但这也很糟糕。
#1
3
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.
最好的方法是创建一个线性的,一维的向量(甚至数组),并使用一对operator()访问它,有关详细信息,请参阅C ++ FAQ Lite。或者使用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';
}
#2
1
Just to poiny out why Cubbi is right, this would be the constructor of the 3d-vector:
只是为了说明为什么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
)
)
);
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.
此外,你不能声明浮点值[] [] [];因为数组驻留在堆栈上,所以编译器必须在编译时知道该数组的大小(例外:C99可变长度数组,但这不是C ++)。你可以声明一个浮动***值; (使用新浮点[c] [r] [d];在ctor中),但这也很糟糕。