首页 > 解决方案 > 矩阵类内存分配和重载

问题描述

我想在构造函数中为矩阵动态分配内存。我想mData成为指向double值的指针。

getvalue() setValue()getter 应该返回 row_x 和 column_x 的值,setter 应该设置 row_x 和 column_x 的值,但是 getter 和 setter 似乎不起作用;

operator +必须检查 2 个相同大小的矩阵,并逐个元素求和。

Operator *还需要检查 2 个相同大小的矩阵,并逐个元素相乘。

Operator ^需要检查是否可以将行乘以第 2 列矩阵,然后执行此操作。

这是我的代码:

class Mat {
private:
    uint16_t mRows;
    uint16_t mCols;
    double * mData;
public:
    Mat(uint16_t r, uint16_t c){
        mRows = r;
        mCols = c;
        mData = new double[mRows * mCols];
    }
    Mat(uint16_t c){
        mCols = c;
        mRows = 1;
        mData = new double [mCols];
    }
    Mat(){
        mRows = 0;
        mCols = 0;
    }
    Mat(const Mat &mat) : mRows(mat.mRows), mCols(mat.mCols), mData(mat.mData){

    }
    double getValue(uint16_t r, uint16_t c){

        double val = mData [r*c + c];
        return val;
    }
    void setValue(uint16_t r, uint16_t c,double value){
        mData[r*c + c] = value;
    }
    ~Mat(){
        
    }
    Mat operator + (const Mat &mat){
        Mat result;
        int ok=0;
        if(mat.mRows == mRows && mat.mCols == mCols){
            ok=1;
            result.mData[mRows*mCols ] = mData[mRows*mCols ] + mat.mData[mat.mRows*mat.mCols];
        }
        if(ok == 0)
           return result.mData[0];
        else
            return result;
    }
    Mat operator * (const Mat &mat){
        Mat result;
        int ok=0;
        if(mat.mRows == mRows && mat.mCols == mCols){
            ok=1;
            result.mData[mRows*mCols] = mData[mRows*mCols] * mat.mData[mat.mRows*mat.mCols];
        }
        if(ok == 0)
            return result.mData[0];
        else
            return result.mData[mRows*mCols];
    }
     Mat operator ^ (const Mat &mat){
        Mat result;
        int ok=0;
        if(mat.mRows == mCols && mat.mCols == mRows){
            ok=1;
            result.mData[mRows] = mData[mRows] * mat.mData[mat.mCols];
        }
        if(ok == 0)
            return result.mData[0];
        else
            return result.mData[mRows];
    }


};

我想继续这个想法,但我不确定我错过了什么

标签: c++classmatrixheap-memory

解决方案


使用std::vector<double>而不是double*使内存管理和复制变得更加容易且不易出错。我还注意到元素明智访问中的一个错误,应该使用r*mCols+c而不是r*c+c. 要解决元素智能矩阵运算的问题,您需要遍历所有元素:

for (size_t r = 0; r < mRows; ++r)
   for (size_t c = 0; c < mCols; ++c)
      result[r*mCols+c] = src1[r*mCols+c] + src2[r*mCols+c]

这是 Mat 的示例实现。我operator+到目前为止只做了,但应该很容易扩展到其他运营商:

class Mat
{
private:
    size_t mRows;
    size_t mCols;
    std::vector<double> mData;
public:
    // constructors
    Mat(size_t rows, size_t cols, double v = 0.0f)
        : mRows(rows), mCols(cols), mData(mRows*mCols, v)
    {}
    Mat(size_t cols, double v = 0.0f)
        : mRows(1), mCols(cols), mData(mRows*mCols,v)
    {}
    Mat()
        : mRows(0), mCols(0), mData()
    {} 

    // automatic copy & move construction just works^TM using std::vector
    Mat(const Mat&) = default;
    Mat(Mat&&) = default;
    // same with automatic copy & move assignment
    Mat& operator= (const Mat&) = default;
    Mat& operator= (Mat&&) = default;

    // element access
    double getValue(size_t r, size_t c) const
    {
        return mData[r*mCols + c];
    }
    void setValue(size_t r, size_t c, double value)
    {
        mData[r*mCols + c] = value;
    }

    // element access through operator():
    // Mat m(3,3); m(1,2)=5.0f;
    double& operator()(size_t r, size_t c)
    {
        return mData[r*mCols + c];
    }
    const double& operator()(size_t r, size_t c) const
    {
        return mData[r*mCols + c];
    }

    // in place addition saves unnecessary memory allocation & copying
    Mat& operator += (const Mat& m)
    {
        if (m.mRows != mRows || m.mCols != mCols)
            throw std::runtime_error("Mat: dimensions don't match");
        // since all matrix elements are contiguous in memory, we can simply to a single for loop
        for (size_t i = 0; i < mData.size(); ++i)
            mData[i] += m.mData[i];
        return *this;
    }

    
    Mat operator + (const Mat& m) const
    {
        if (m.mRows != mRows || m.mCols != mCols)
            throw std::runtime_error("Mat: dimensions don't match");
        // copy this Mat into a new Mat
        Mat result(*this);
        // add m to result in place and return result
        result += m;
        return result;
    }
};

推荐阅读