【问题标题】:How to store a matrix of custom objects in C++ [closed]如何在 C++ 中存储自定义对象的矩阵 [关闭]
【发布时间】:2025-12-16 14:10:01
【问题描述】:

我有一个我定义的 C++ 类,并希望存储该类实例的矩阵。有没有人这样做的一些代码示例?我找到了向量的例子,但我不确定这是否是最好的解决方案,或者是否有一些“更简单”的东西(更像是 Objective-C 风格 -> NSArray * array)。

有什么建议吗?

【问题讨论】:

  • 您是否试图在使用容器时阻止复制构造函数调用?如果是这样,请查看具有类指针的二维向量,其中每个实例都是从空闲存储区分配的。稍后,您将不得不使用您最喜欢的遍历循环手动释放分配的内存。一定要声明一个虚拟析构函数。否则,您将面临无法调用派生类的析构函数的风险。

标签: c++ matrix


【解决方案1】:

在这个宇宙中永远不存在“最佳解决方案”。有很多方法可以在 C++ 中呈现矩阵,这完全取决于您的选择。

1. C 风格的幼稚解决方案

使用多维数组(静态或动态):

MyClass arr[size_y][size_x];

MyClass** arr;

用法:

arr[y][x] = MyClass(a, b, c);  // writing to (x, y)

代码简单、性能差(引用的局部性)、容易发生内存泄漏(手动内存管理)和容易出错(例如访问越界)

2。 C 风格的解决方案

使用普通数组而不是多维数组。

  MyClass arr[size_y * size_x];
  arr[y * size_x + x] = MyClass(a, b, c); // writing to (x, y)

缓存友好,编码有点困难,每次计算索引仍然会泄漏和容易出错。

3. C++程序风格解决方案

同上,但使用std::array(用于固定大小矩阵)或std::vector(用于动态大小矩阵)而不是普通数组。

std::array<MyClass, size_x * size_y> arr;
arr[y * size_x + x] = MyClass(a, b, c); // writing to (x, y)

缓存友好,没有泄漏,仍然存在超出范围。

4.面向对象的 C++ 解决方案

使用std::array(对于固定大小的矩阵)或std::vector(对于动态大小的矩阵)作为底层存储来编写(模板化)类。重载operator()

template<class T, size_t rows, size_t cols>
class Matrix
{
    std::array<T, rows * cols> m_Data;
public:
    T& operator()(size_t y, size_t x)
    {
        return m_Data[y * cols + x];
    }

    // more methods go here
}

用法:

 Matrix<MyClass, size_x, size_y> arr;
 arr(x, y) = MyClass(a, b, c); // writing to (x, y)

缓存友好,无泄漏,程序员友好的语法。聪明的! ;)

5.使用一些库

如果您需要一些线性代数细节,例如稀疏矩阵,或者您只是不想重新发明*,请去谷歌搜索一些库。以下是一些示例:Boost uBlasArmadilloEigen。智能、方便,但需要一些学习。

【讨论】:

  • 4b:使用重载operator[] 的代理类。让您的 Matrix 类的 operator[] 返回一个代理。代理自己的operator[] 返回T
【解决方案2】:

您可以通过嵌套容器来创建矩阵,例如C++11std::array.

class Foo {
    /* ... */
};

int main() {
    // Create 3x3 matrix of Foo's.
    std::array<std::array<Foo, 3>, 3> mat;
}

或者使用普通的旧多维数组。

Foo mat2[3][3];

如果您在编译时不知道大小,请使用std::vector

std::size_t n = 3;
std::size_t m = 3;
std::vector<std::vector<Foo>> mat3(n, std::vector<Foo>(m));

【讨论】:

  • 需要说,嵌套数组往往是个坏习惯。他们引入了方便的元素访问语法作为性能的权衡。只有当你真的别无选择时,我才会使用它们。
【解决方案3】:

如果 Foo 是您的班级的名称,那么这将创建一个矩阵

Foo matrix[4][4]; //for a 4x4 matrix

Foo **matrix;

您可以使用 newma​​lloc 对其进行初始化。

【讨论】:

  • 在 C++ 中不鼓励使用 C 数组和原始指针,原因有很多。 -1.
  • 注意:在这种情况下使用 malloc() 是完全错误的!
  • 在我的辩护中,我想指出 C++ 中的 new 运算符最终归结为 malloc 调用。为此,您可以查看 GCC 和 Clang 的代码。此外,由于它只是一个矩阵而不是类的对象,因此没有构造函数进入图片。
最近更新 更多