c++ - 矩阵类内存分配和重载
问题描述
我想在构造函数中为矩阵动态分配内存。我想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];
}
};
我想继续这个想法,但我不确定我错过了什么
解决方案
使用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;
}
};
推荐阅读
- flutter - Flutter 发送多条消息,分享插件
- c# - 无法加载文件或程序集 System.Collections,版本 = 4.0.11.0
- javascript - 找不到名称“Highcharts”.ts(2304)
- html - 想要创建具有相似参数的自定义 numericRangeInput
- java - 获取 I/O 异常
- .net - 为什么我的 AWS Lambda 在 ARM64 架构中运行时会崩溃?
- r - 奇怪的 R 包行为:“找不到函数”
- string - 条件 WHERE 字符串不带/带空格
- java - 无法将 dockerized springboot 应用程序连接到未 dockerized postgres 数据库(localhost)
- sed - 我在 RHEL 8.3 中收到 sed 命令的“无效范围结束”