C 如何将一系列类别视为主要类型的数组
C++ How to treat an array of classes as an array of primary types?
我有此代码:
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的值)
首先,该标准不能定义应如何实现参考,但是它们几乎可以肯定会在您的班级中占据实际记忆,这是指指针成员会遇到的,破坏了您的连续数据包装您''重新希望....
如果您的重点更多地放在顶点容器上,并且您只希望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];
};
您可以具有成员函数:
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]; }
};
您也可以省略构造函数并具有聚合,如果更合适。
带有3个float
参考的values
指针的数组(指向3 floats
的数组)(x
,y
,z
)。您可能更像是:
float & x() { return values[0]; }
float & y() { return values[1]; }
float & z() { return values[2]; }
如果我了解您对模型中连续数据的要求,那么您的向量确实是模型中特定数据的特定三重数据的别名。无需浮子存储。
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]; }
对于保证的连续数组,您需要将数据复制到数组中,或使用特定于编译器的保证,尤其是
- 没有填充物,
,如果您还要以Vector3
的实例访问数组的三胞胎,那
- 在任意地址访问
Vector3
不会导致陷阱或效率低下(我们进入 Alignment
)。
碰巧的是,某些常见库(例如OpenCV)确实为其内部图像缓冲区做出了这样的假设。
,但我不确定我所看到的代码尚未适应平台。因此,实际上您有这些选择:
-
将数据连续地复制到数组(或从中)和/或
-
使用提供此类功能的现有库,例如OpenCV。
请注意,使用成员函数而不是引用可以购买任何wrt。对于连续的数组问题,但它确实使Vector3
有可能分配。
在进一步的反射上,我可能太触发了以上书写。因为如果您可以保证总尺寸3*sizeof(float)
,而这几乎是给定的(只需摆脱这些参考),那么您可以保证您可以在任何可以容纳float
的地址访问Vector3
,因为C 可以保证没有填充的阵列,没有填充,而且由于在这样的数组中,Vector3
最终可以在任何可以容纳float
的地址处。因此,实践中的问题减少了为支持编译器或编译器配置的决定,这些编译器或编译器配置无法使Vector3
大小3*sizeof(float)
。
即。
struct Vector3
{
float x, y, z;
auto operator[]( int i ) -> float& { return (&x)[i]; }
auto operator[]( int i ) const -> float const& { return (&x)[i]; }
};
static_assert( sizeof( Vector3 ) == 3*sizeof( float ), "Ungood Vector3 size" );
使用没有中间访问说明符的成员可以保证在地址顺序上增加。
免责声明:避免袖口代码,没有由编译器的手触摸。
如果保留vector3类A吊舱,则应该能够简单地将顶点投射到浮点数组:
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] << ", ";
}
}
唯一的问题可能是结构的反词,但是如果您使用C 11,则使用Allignas alignas(alignof(float[3]))
有一种标准方法来对结构进行吻合。我不知道这是否真的需要。另外,C 11给出了有关对vector3的操作的很多选择,同时仍将其视为POD类型。
- C++默认情况下,指针类型数组的元素是否保证初始化为 nullptr?
- 类型数组?
- 如何在使用 make_unique<T[]>() 制作的模板类型数组上使用 std::fill?
- 将基本类型数组中的内存重新用于不同(但仍然是基本)类型的数组合法吗
- 在C++中返回基元类型数组(Java比较)
- 如何返回 QVariant 类型数组
- 如何在本机 c++ jni 中实现 java 类型数组
- 模板类型数组的模板类型数组
- 如何确定未知类型数组的索引是否为空
- 复杂类型数组的静态初始化
- 访问基类型数组成员(Int-to-type习惯用法)
- 如何将 char 类型数组传递给函数并将第一个字符数组复制到第二个图表数组并使用 c++ 进行比较
- 如何在C 中制作结构类型数组
- 如何创建结构类型数组的地图对象
- C++类类型数组
- C++中的Matlab类型数组
- 节点C++插件 - 当类型数组(Float32Array)作为参数传递时,如何访问它?
- 如何将二维字符类型数组逐行保存到 c 中的.txt文件中
- C++:用户定义的类型数组出错
- 在双精度类型数组中使用 memset()