【问题标题】:C++ class memory layoutC++ 类内存布局
【发布时间】:2016-09-11 11:03:35
【问题描述】:

如果有可能,以及最终如何可能,我想现在以一种特殊的方式实现一个类,以便您可以创建该类的向量,并在填充它之后迭代类属性,而无需迭代向量。

这是一个例子:

class Vertex3f
{
    public:
        union
        {
            float vec[3];
            struct
            {
                float x, y, z;
            };
        };

    public:
        Vertex3f();
        ~Vertex3f();

    ...
}

然后创建这个类的std::vector,填充它并访问所有类的实例属性:

Vertex3f v1, v2;
v1.x = 10.0f;
v1.y = 0.0f;
v1.z = 5.0f;
v2.x = 8.0f;
v2.y = -5.0f;
v2.z = 3.0f;

// Create and fill the vector
std::vector<Vertex3f> vec;
vec.push_back(v1);
vec.push_back(v2);

// Get all the vertices data in one go
// This is the tricky part I'm not sure it can be done
size_t size = vec.size() * (sizeof(float) * 3);
float* vertices = new float[size];
memcpy(vertices, &vec[0].x, size);

现在 Bullet Physics 库出于性能原因做了类似的事情,我也想做同样的事情,但我不明白怎么做。

【问题讨论】:

  • 您的代码有一个小问题:不能保证float vec[3] 和您的结构大小相同。如果系统的编译器本机填充是 64 位,则结构将是数组大小的两倍。
  • 您可能应该查看 C++ 对 POD typesmemory alignment 的说明
  • 这正是我所关心的。 float vec[3] 的大小与我的类不同,因为该类还将包含成员函数和其他属性
  • 除了来自 telvaz 的链接,您还需要了解严格的别名规则。这都是非常可怕的事情——你需要做这件事有多严重?
  • 好吧,我想在我正在编写的图形引擎中使用它,例如,将网格顶点复制到 OpenGL 缓冲区。正如我现在所做的那样,我创建了一个临时的 float 数组,在其中复制所有顶点数据并使用它来将数据传递到 OpenGL 缓冲区

标签: c++ memory-layout


【解决方案1】:

如果您只想要功能,我有另一个可能适合您的实现。

您可以创建浮点数组,然后为 vec3 类提供指向该向量中适当点的 x 位置的指针。

类似:

class vec3
{
public:
    vec3(float* valN)
    {
        val = valN;
    }

    float x()
    {
        return *val;
    }
private:
    float* val;
};

int size = 3;
float* fArr = (float*)malloc(sizeof(float)*size);

fArr[0] = 8;
fArr[1] = 9;
fArr[2] = 10;

std::vector<vec3> points;
vec3 p(&fArr[0]);

points.push_back(p);

float out = points[0].x();

out 应该在这里结束为 8.0。

【讨论】:

  • 是的,我可以这样做,但考虑使用 std::vector&lt;float&gt; 代替 fArr 会使这无用,因为 std::vector 在添加/删除元素时会在内存中四处移动,而我'想保留向我的网格添加/删除顶点的可能性。另外,这样我必须始终有float 数组作为支持,即使我只需要一个简单的vec3 来进行一些计算
  • 如果您事先使用 vec.resize() 为向量分配内存,则可以避免移动内存的问题。重载 vec3 构造函数以允许它创建自己的数组也很容易。
  • 是的,这似乎可行。我试试看
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-03-07
  • 2010-12-10
  • 2020-09-30
  • 2012-07-09
  • 2019-05-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多