首页 > 解决方案 > 将(C 类)指针转换为 C++ 矩阵

问题描述

我想将矩阵从一个函数传递到另一个函数,所以我做了:

#include <cstdlib>
using namespace std;

const int N = 2;

void init_matrix(int (*matrix)[N]) 
{
    for (int i = 0; i < N; ++i)
        for (int j = 0; j < N; ++j)
            matrix[i][j] = 1;
}

int main() 
{
    int *x = (int*)malloc(N*N*sizeof(int));
    init_matrix( (int (*)[N]) x );
    return 0;
}

如何让通话init_matrix()更轻松?我想象它像init_matrix(x, N)

请注意,我有点避免std::vector,因为我很快就会使用并行编程(pthreads、OpenMP、MPI)。所以我会要求一个没有std构建矩阵方法的解决方案。

标签: c++matrixmultidimensional-arrayc++14raw-pointer

解决方案


只是不要。

多维数组并不是 C++ 最好的地方。在这里它仍然是可以接受的,因为 N 是一个编译时间常数,但如果它是一个运行时变量,你会被关闭,因为标准 C++ 不支持 VLA(即使它们被一些实现支持作为实现扩展,如 gcc 和铛)。

因此,如果您真的需要处理真正的 2D 数组,只需使用一个自定义类,该类包含一个std::array用于固定编译时间维度的底层或一个用于运行时维度的向量以获得总大小,并为其提供 2d 访问器。由于std::arrays和向量是对象,因此您可以避免资源复制和移动噩梦(*)。

一个简化的实现可能是:

class matrix {
   std::vector<int> vec;
   int  rows;
   int cols;

public:
   matrix(int i, int j): rows(i), cols(j), vec(i * j) {}

   int& at(int i, int j) {
       return vec[j + i * cols];
   }

   const int& at(int i, int j) const {
       return vec[j + i * cols];
   }
};

这样,底层结构仍然是一个真正的二维数组,并且您确实有方法使用它的二维

这里还缺少什么:

  • 索引和大小可能应该size_t代替int
  • 可以在at方法中测试索引是否在可接受的范围内-如果您不检查它们,则不应调用该函数at...
  • 其他构造函数在现有二维数组之上构建矩阵(例如,可能来自 C 遗留代码)

补充说明:

你说你想避免可能的多线程的向量。首先,我无法想象为什么向量的多线程安全性不如手动分配的动态数组。其次,如果您确实需要手动分配,则必须遵循三/五规则,并在自定义析构函数之外实现自定义复制/移动构造函数和赋值运算符。


(*) 我有一个项目要编写一个通用的多维容器支持operator []和迭代器,所以我知道这是一项相当复杂的任务。我已经向代码审查提交了一个预版本,但它仍然远非简单可用。


推荐阅读