将数组传递给类函数

Passing array to class function C++

本文关键字:类函数 数组      更新时间:2023-10-16

我有一个二维数组,组织为

float vertices[3][3]

在我的程序的一个迭代循环中,我在调试器中看到数组填充如下:

vertices[0] = {-1, -1, 1}
vertices[1] = {-1, -.5, .5}
vertices[2] = {-.5, -1, .5}

然后将三个顶点传递给我的三角形类。

Triangle *t = new Triangle(vertices[0], vertices[1], vertices[2]);
triangles.push_back(*t);

三角形构造函数的编码如下:

Triangle::Triangle(float *a, float *b, float *c)
{
    memcpy(v1, a, sizeof(a));
    memcpy(v2, b, sizeof(b));
    memcpy(v3, c, sizeof(c));
}

调试器现在显示

v1 = {-1, -431602080, -431602080}
v2 = {-1, -431602080, -431602080}
v3 = {-.5, -431602080, -431602080}

调试器还显示,a/b/c只有1个元素长?显然只传递了数组的第一个元素?

sizeof (a)

sizeof(浮动*)

不是3x浮点数,它是1个指针。传递额外的参数size_t number_of_members_in_array并替换

memcpy(v1, a, sizeof(a));

memcpy(v1, a, sizeof(*a) *number_of_members_in_array);

Triangle::Triangle(float *a, int numA, float *b, int numB, float *c, int numC)
{
    memcpy(v1, a, sizeof(float) * numA);
    memcpy(v2, b, sizeof(float) * numB);
    memcpy(v3, c, sizeof(float) * numC);
}

这里的问题是您使用sizeof操作符,因为一旦数组衰减为指针,它就会丢失所有大小信息,并且在函数中执行例如sizeof(a)只会给您指针的大小而不是它指向的内容。

在c++中有一个简单的方法来解决这些问题,那就是使用std::vectorstd::array来代替。如果您出于某种原因不想使用这些方便的类,那么您需要以某种方式将大小传递给函数,例如作为参数或作为模板形参。

在您的例子中,sizeof(a)将给您指针的大小,而不是它所指向的数据。这是因为a是一个float指针!

这样做:传递元素数量(在您的例子中是3)作为参数:

    Triangle::Triangle(float *a, float *b, float *c, int numElements)
    {
        memcpy(v1, a, sizeof(a) * numElements);
        memcpy(v2, b, sizeof(b) * numElements);
        memcpy(v3, c, sizeof(c) * numElements);
    }

对于预期的固定大小的float数组,有一种替代方法:

Triangle::Triangle(const float (&a)[3], const float (&b)[3], const float (&c)[3])

但传递size或使用std::array<float, 3>std::vector<float>似乎更简单。

除了其他解决方案之外,我想指出您的代码存在内存泄漏:

Triangle *t = new Triangle(vertices[0], vertices[1], vertices[2]);
triangles.push_back(*t);

当你执行push_back(*t)时,你是在推入*t处分配对象的副本,而不是指针t的副本。vector在内部为另一个Triangle分配空间,并将给定的对象复制到其中。在此代码之后,该指针丢失,分配的对象被孤立/泄漏。

如果你想保持你的三角形作为单独分配的对象,那么triangles应该是一个vector<Triangle *>,代码应该看起来像这样:

Triangle *t = new Triangle(vertices[0], vertices[1], vertices[2]);
triangles.push_back(t);

如果你想保持triangles作为vector<Triangle>,那么你需要更像这样的东西:

Triangle t(vertices[0], vertices[1], vertices[2]);
triangles.push_back(t);

或者,如果您的编译器/stl实现支持vector::emplace_back(),则更简单:

triangles.emplace_back(vertices[0], vertices[1], vertices[2]);

直接对vector中的新项进行构造。