You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

方阵乘法实现问题求助:矩阵类乘法逻辑待完善

解决方阵矩阵乘法的实现问题

看起来你已经搭好了矩阵类的基础框架,但在实现仅支持同阶方阵相乘的乘法运算符时遇到了逻辑漏洞。核心问题在于你没有先严格校验输入的合法性,而且乘法循环的逻辑也不完整。下面我帮你修正并完善这段代码:

先说说你现有代码的问题

你的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("行或列索引超出方阵范围!");
        }
    }
};

关键要点解释

  1. 合法性校验:在乘法运算开始前,先检查两个矩阵的边长是否相等,不满足则抛出std::invalid_argument异常,调用者能立刻知道错误原因,而不是得到一个无效的矩阵。
  2. 正确乘法逻辑:用三重循环实现标准矩阵乘法,注意一维数组存储矩阵时的索引转换规则(行号*边长 + 列号)。
  3. 内存安全:添加析构函数释放内存,同时实现拷贝构造和拷贝赋值运算符,避免浅拷贝导致的内存重复释放问题。
  4. 方阵约束:类的设计完全针对方阵,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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:45:34