我有这段代码:
class Vector3
{
public:
Vector3() : x(values[0]), y(values[1]), z(values[2])
{ x = y = z = 0; }
float& x;
float& y;
float& z;
private:
float[3] values;
};
class Model
{
public:
Vector3 vertices[64];
};
我正在做这个矢量类,因为我想在代码中处理X
,Y
,Z
的值,但对于某些操作,我需要一个连续的数组要传递给函数的值。
所以vertices[64]
的整个数组需要[x0][y0][z0][x1][y1][z1][x2][y2][z2]
等。
但如果我这样做:
//Get first address:
void* firstAddress = &vertices[0];
//Or
void* firstAddress = vertices;
我没有连续数组,因为我需要它(数据全部搞砸了),我猜它是因为我在Vector3
类中的指针。
我有什么方法可以获得我想要的功能吗? (有一个浮点数,但处理值为x,y,z)
答案 0 :(得分:1)
您可以改为使用成员函数:
class V3
{
float data[3];
public:
V3() : data{0,0,0} {}
float & x() { return data[0]; }
float & y() { return data[1]; }
float & z() { return data[2]; }
};
你也可以省略构造函数并有一个聚合,如果那更合适的话。
答案 1 :(得分:1)
首先,标准没有定义如何实现引用,但是它们几乎肯定会占用类中的实际内存而非指针成员,破坏了你希望的连续数据包.... / p>
如果您的焦点更多地放在顶点容器上,并且您只想让x / y / z成员访问其中的元素,那么您可以尝试以下方法:
template <size_t N>
class Vertices
{
public:
class Proxy
{
public:
Proxy(float* p) : x(p[0]), y(p[1]), z(p[2]) { }
float& x;
float& y;
float& z;
};
Proxy operator[](size_t n) { return Proxy(&d_[n * 3]); }
const Proxy operator[](size_t n) const { return Proxy(&d_[n * 3]); }
private:
float d_[N * 3];
};
答案 2 :(得分:0)
你拥有的values
指针数组(指向3个floats
的数组)包含3个float
引用(x
,y
,{{ 1}})。你可能更喜欢蚂蚁:
z
答案 3 :(得分:0)
对于保证连续的数组,您需要将数据复制到数组中,或者使用特定于编译器的内存布局保证,特别是
如果您还希望将数组的三元组作为Vector3
实例访问,那么
Vector3
不会导致陷阱或效率低下(我们在这里进入 alignment )。恰巧一些常见的库(如OpenCV)会对其内部图像缓冲区做出这样的假设。
但我不完全确定我见过的代码不适合平台。所以,在实践中你有这些选择:
将数据连续复制到数组(或从中复制)和/或
使用提供此类功能的现有库,例如OpenCV。
请注意,使用成员函数而不是引用会购买任何东西。对于连续的数组问题,它确实使Vector3
可以分配。
在进一步思考时,我可能过于高兴地写了上述内容。如果您可以保证总大小3*sizeof(float)
,并且这几乎是给定的(只是删除那些引用),那么您可以保证可以在任何可以容纳{{{{}}的地址访问Vector3
1}},因为C ++保证数组没有填充,并且因为在这样的数组中,float
可以在任何可以容纳Vector3
的地址处结束。因此,实践中的问题减少了,无法支持无法使float
大小为Vector3
的编译器或编译器配置。
即
3*sizeof(float)
使用没有中间访问说明符的成员保证增加地址顺序的事实。
免责声明:关闭袖口代码,不要被编制者的手接触。
答案 4 :(得分:0)
如果我理解您对模型中连续数据的要求,那么您的Vector实际上是模型中特定三重数据的别名。不需要浮动存储。
class Model
class Vector
Vector(Model *model_, size_t idx_) : model(model_),idx(idx_) { };
Model *model;
size_t idx;
float & x() { return model->data[3*idx]; }
float & y() { return model->data[3*idx+1]; }
float & z() { return model->data[3*idx+2]; }
float data[64 * 3];
Vector vectors[64];
Model() {
...
for( size_t ii = 0; ii < 64; ii++ ) {
vectors[ii] = new Vector(this,ii);
}
Vector & vector(size_t idx) { return vectors[ii]; }
答案 5 :(得分:0)
如果你将Vector3类保持为POD,你应该能够简单地将顶点转换为浮点数组:
struct Vector3 {
float x;
float y;
float z;
};
class Model
{
public:
Vector3 vertices[64];
float* data() {
return reinterpret_cast<float*>(vertices);
}
};
int main() {
Model m;
for(int i = 0; i < 64; ++i) {
m.vertices[i] = {10+i,100+i,1000+i};
}
float *data = m.data();
for(int i= 0; i < 64*3; ++i) {
std::cout << data[i] << ", ";
}
}
唯一的问题可能是结构的Allignment,但是如果你使用c ++ 11,有一种标准方法可以使用allignas alignas(alignof(float[3]))
来对结构进行分配。我不知道这是否真的需要。
此外,c ++ 11提供了很多关于如何处理Vector3的选项,同时仍将其视为POD类型。