【发布时间】:2019-01-03 21:34:25
【问题描述】:
我正在构建一个模板矩阵类,用于我未来的 c++ 代码。关于重载运算符的值传递、异常与断言以及通用类设计,我有几个问题。
我是否正确传递了这些值?它有效率吗?我还能做些什么来让它变得更好?
此库的构建考虑了未来的应用程序设计(终端或 gui),用户可以在其中定义自己的矩阵并运行计算。在这种情况下使用异常而不是断言会更好吗?
-
我查看了 c++ 的 5 规则,其中指出:
因为用户定义的析构函数、复制构造函数或复制赋值操作符的存在阻止了隐式定义移动构造函数和移动赋值运算符,任何需要移动语义的类,都必须声明所有五个特殊成员函数。
我可以通过不使用这三个规则中的任何一个而侥幸逃脱吗?** 使这个类更实用的标准方法是什么?
我在我的程序中定义了减法、乘法和除法(标量),其结构与提供的加法运算符定义相同/相似,因此此处不需要所有代码。
接受对整体设计的任何硬性建议或批评!
#ifndef MACMATRICES_H
#define MACMATRICES_H
#include <vector>
#include <iomanip>
#include <iostream>
#include <exception>
#include "../../DMF-Terminal.h"
namespace DMF
{
template <typename T>
class matrix
{
public:
// Constructors
matrix();
matrix(int p_rows, int p_columns);
// Operators
std::vector<T>& operator[] (size_t i) { return m[i]; }
matrix<T> operator+(const matrix<T>& rhs);
matrix<T> operator+(const T& rhs);
matrix<T>& operator+=(const matrix<T>& rhs);
matrix<T>& operator+=(const T& rhs);
// Class Methods
void print() const;
matrix<T> inverse();
T determinant();
// Observers
bool isSquare() const;
int rowSize() const { return m_rows; }
int colSize() const { return m_cols; }
private:
int m_rows, m_cols;
std::vector< std::vector<T> > m;
};
/* 构造函数 -------------------------------------------- ----------------------------------------------------*/
template <typename T>
matrix<T>::matrix(){}
template <typename T>
matrix<T>::matrix(int p_rows, int p_cols) :
m(p_rows, std::vector<T>(p_cols)), m_rows(p_rows), m_cols(p_cols) {}
/* 加法 -------------------------------------------- -------------------------------------------------------*/
template <typename T>
matrix<T> matrix<T>::operator+(const matrix<T>& rhs)
{
try
{
if((this->rowSize() == rhs.rowSize()) && (this->colSize() == rhs.colSize()))
{
matrix<T> sum (this->rowSize(), this->colSize());
for(int i = 0; i < this->rowSize() ; ++i)
{
for(int j = 0; j < this->colSize(); ++j)
sum.m[i][j] = this->m[i][j] + rhs.m[i][j];
}
return sum;
}
else throw std::runtime_error("Cannot add matrices, invalid row/column sizes.");
}
catch (std::exception &e)
{
std::cout << "Error: " << e.what(); DMF::wait();
}
}
template <typename T>
matrix<T> matrix<T>::operator+(const T& rhs)
{
matrix<T> sum (this->rowSize(), this->colSize());
for(int i = 0; i < this->rowSize() ; ++i)
{
for(int j = 0; j < this->colSize(); ++j)
sum.m[i][j] = this->m[i][j] + rhs;
}
return sum;
}
template <typename T>
matrix<T>& matrix<T>::operator+=(const matrix<T>& rhs)
{
try
{
if((this->rowSize() == rhs.rowSize()) && (this->colSize() == rhs.colSize()))
{
for(int i = 0; i < this->rowSize() ; ++i)
{
for(int j = 0; j < this->colSize(); ++j)
this->m[i][j] += rhs.m[i][j];
}
return *this;
}
else throw std::runtime_error("Cannot add matrices, invalid row/column sizes.");
}
catch (std::exception &e)
{
std::cout << "Error: " << e.what(); DMF::wait();
}
}
template <typename T>
matrix<T>& matrix<T>::operator+=(const T& rhs)
{
matrix<T> sum (this->rowSize(), this->colSize());
for(int i = 0; i < this->rowSize() ; ++i)
{
for(int j = 0; j < this->colSize(); ++j)
this->m[i][j] += rhs;
}
return *this;
}
}
#endif /* MACMATRICES_H */
截至目前,此代码可在迷你终端程序中运行。我还重载了 matrix * matrix 和 matrix *= matrix 运算符,它似乎工作正常,结果矩阵大小正确。
【问题讨论】:
-
这很有意义。我只是在最后一秒把它们扔进去了。谢谢!
-
为了性能,不要使用向量的向量。使用带有成员函数的单个内存块来访问它。并在尝试将其转换为模板之前将其编写为
int的非模板类。 -
您忘记在默认构造函数中初始化所有成员。但是,存在一个空矩阵是否有意义?
-
@molbdnilo 默认构造函数用于测试我的乘法运算符的赋值。我猜我真的不需要它,但是我想像使用 std::vector 一样使用列表初始化来实现构造函数。最简单的方法是什么?
-
@NeilButterworth 我希望我可以在我的代码中进一步使用 std::vector 成员函数。您的意思是我应该将矩阵作为动态分配的二维数组吗?
标签: c++ class templates matrix operator-overloading