方阵乘法实现问题求助:矩阵类乘法逻辑待完善
解决方阵矩阵乘法的实现问题
看起来你已经搭好了矩阵类的基础框架,但在实现仅支持同阶方阵相乘的乘法运算符时遇到了逻辑漏洞。核心问题在于你没有先严格校验输入的合法性,而且乘法循环的逻辑也不完整。下面我帮你修正并完善这段代码:
先说说你现有代码的问题
你的operator*里虽然写了if(mSize == mat.mSize)的判断,但即使不满足条件,仍然会初始化结果矩阵mul并分配内存,这会导致错误的对象生成甚至内存问题。我们需要先把合法性校验放在最前面,不满足条件直接终止操作并明确报错。
修正后的完整实现
#include <stdexcept> // 用于抛出标准异常 class matrix { private: int mSize; // 因为只支持方阵,mSize直接代表n×n中的边长n int* mP; public: // 默认构造函数 matrix() : mP(nullptr), mSize(0) {} // 带边长的构造函数,方便创建指定大小的方阵 explicit matrix(int size) : mSize(size) { if (size > 0) { mP = new int[size * size](); // 初始化所有元素为0 } else { mP = nullptr; mSize = 0; } } // 析构函数:必须手动释放内存,避免泄漏 ~matrix() { delete[] mP; mP = nullptr; mSize = 0; } // 拷贝构造函数:避免浅拷贝导致的内存重复释放 matrix(const matrix& other) : mSize(other.mSize) { if (mSize > 0) { mP = new int[mSize * mSize]; for (int i = 0; i < mSize * mSize; ++i) { mP[i] = other.mP[i]; } } else { mP = nullptr; } } // 拷贝赋值运算符:同样处理浅拷贝问题 matrix& operator=(const matrix& other) { if (this != &other) { delete[] mP; // 先释放当前对象的内存 mSize = other.mSize; if (mSize > 0) { mP = new int[mSize * mSize]; for (int i = 0; i < mSize * mSize; ++i) { mP[i] = other.mP[i]; } } else { mP = nullptr; } } return *this; } // 核心:仅支持同阶方阵相乘的乘法运算符 matrix operator*(const matrix& mat) const { // 第一步:严格校验是否为同阶方阵 if (mSize != mat.mSize) { throw std::invalid_argument("仅支持同阶方阵相乘!两个矩阵的边长必须相等。"); } if (mSize == 0) { throw std::invalid_argument("空矩阵无法进行乘法运算。"); } // 初始化结果矩阵 matrix mul(mSize); // 第二步:实现标准方阵乘法逻辑 // 规则:结果矩阵C[i][j] = sum(A[i][k] * B[k][j]),k从0到mSize-1 for (int i = 0; i < mSize; ++i) { // 遍历结果矩阵的行 for (int j = 0; j < mSize; ++j) { // 遍历结果矩阵的列 int sum = 0; for (int k = 0; k < mSize; ++k) { // 计算行乘列的累加和 // 一维数组存储矩阵的索引转换:行i、列j的元素 = i*mSize + j sum += mP[i * mSize + k] * mat.mP[k * mSize + j]; } mul.mP[i * mSize + j] = sum; } } return mul; } // 可选:添加设置元素的方法,方便测试 void setElement(int row, int col, int value) { if (row >= 0 && row < mSize && col >=0 && col < mSize) { mP[row * mSize + col] = value; } else { throw std::out_of_range("行或列索引超出方阵范围!"); } } // 可选:添加获取元素的方法 int getElement(int row, int col) const { if (row >= 0 && row < mSize && col >=0 && col < mSize) { return mP[row * mSize + col]; } else { throw std::out_of_range("行或列索引超出方阵范围!"); } } };
关键要点解释
- 合法性校验:在乘法运算开始前,先检查两个矩阵的边长是否相等,不满足则抛出
std::invalid_argument异常,调用者能立刻知道错误原因,而不是得到一个无效的矩阵。 - 正确乘法逻辑:用三重循环实现标准矩阵乘法,注意一维数组存储矩阵时的索引转换规则(
行号*边长 + 列号)。 - 内存安全:添加析构函数释放内存,同时实现拷贝构造和拷贝赋值运算符,避免浅拷贝导致的内存重复释放问题。
- 方阵约束:类的设计完全针对方阵,
mSize直接代表边长,不需要额外存储行/列数,简化了逻辑。
测试示例
#include <iostream> int main() { try { // 创建两个2×2的方阵 matrix a(2); a.setElement(0, 0, 1); a.setElement(0, 1, 2); a.setElement(1, 0, 3); a.setElement(1, 1, 4); matrix b(2); b.setElement(0, 0, 5); b.setElement(0, 1, 6); b.setElement(1, 0, 7); b.setElement(1, 1, 8); // 执行乘法 matrix c = a * b; // 输出结果 std::cout << "结果矩阵:" << std::endl; for (int i = 0; i < 2; ++i) { for (int j = 0; j < 2; ++j) { std::cout << c.getElement(i, j) << " "; } std::cout << std::endl; } // 尝试用不同大小的矩阵相乘,会触发异常 matrix d(3); matrix e = a * d; } catch (const std::exception& e) { std::cerr << "错误:" << e.what() << std::endl; return 1; } return 0; }
内容的提问来源于stack exchange,提问作者user9664805
相关产品推荐
相关产品推荐

