Итак, у меня есть свой собственный класс матрицы, и я попытался перегрузить операторы +
и +=
для этого класса следующим образом:
template <class T>
void Matrix<T>::operator+=(Matrix& mat) {
if (this->m_rows != mat.m_rows || this->m_cols != mat.m_cols) {
cerr << "Matrix rows/cols don't match" << endl;
}
else {
for (unsigned int i = 0; i < this->m_rows; i++) {
for (unsigned int j = 0; j < this->m_cols; j++) {
this->m_vec[i * this->m_cols + j] += mat.m_vec[i * this->m_cols + j];
}
}
}
}
template <class T>
Matrix<T> operator+(Matrix<T> mat1, Matrix<T>& mat2) {
if (mat1.get_rows() != mat2.get_rows() || mat1.get_cols() != mat2.get_cols()) {
cerr << "Matrix rows/cols don't match" << endl;
}
else {
mat1 += mat2;
return mat1;
}
}
(я пытаюсь сделать +
оператор цепочки и +=
(не цепочка. Матрица представлена одномерным массивом)
Однако, когда я пытаюсь добавить две матрицы, программа отказывается добавлять их (сообщение об ошибке отсутствует). Я подозреваю, что может быть что-то не так с моими конструкторами перемещения / копирования, операторами назначения перемещения / копирования или моим деструктором, но я не могу понять, что не так.
// Copy constructor
template <class T>
Matrix<T>::Matrix(Matrix& obj) {
size_t rows = obj.get_rows();
size_t cols = obj.get_cols();
this->m_rows = rows;
this->m_cols = cols;
this->m_capacity = rows * cols;
this->m_vec = new T[rows * cols];
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
this->m_vec[j + i * cols] = obj(i, j);
}
}
}
// Move constructor
template <class T>
Matrix<T>::Matrix(Matrix&& obj)
: m_rows(0)
, m_cols(0)
, m_capacity(0)
, m_vec(nullptr)
{
m_rows = obj.get_rows();
m_cols = obj.get_cols();
m_capacity = obj.get_capacity();
m_vec = obj.m_vec;
obj.m_rows = 0;
obj.m_cols = 0;
obj.m_capacity = 0;
obj.m_vec = nullptr;
}
// Destructor
template <class T>
Matrix<T>::~Matrix() {
delete[] m_vec;
}
// Copy assignment operator
template <class T>
Matrix<T>& Matrix<T>::operator=(const Matrix& obj)
{
m_rows = obj.get_rows();
m_cols = obj.get_cols();
m_capacity = obj.get_capacity();
m_vec = obj.m_vec;
return *this;
}
// Move assignment operator
template <class T>
Matrix<T>& Matrix<T>::operator=(Matrix&& obj)
{
if (this != &obj)
{
delete[] m_vec;
m_rows = obj.get_rows();
m_cols = obj.get_cols();
m_capacity = obj.get_capacity();
m_vec = obj.m_vec;
obj.m_rows = 0;
obj.m_cols = 0;
obj.m_capacity = 0;
obj.m_vec = nullptr;
}
return *this;
}
// Matrix class properties
class Matrix{
private:
size_t m_rows;
size_t m_cols;
size_t m_capacity;
T* m_vec;
}
Я совершенно новый на C ++, и я впервые пытаюсь создать конструкторы / операторы копирования / перемещения, поэтому может быть что-то очевидное, чего мне не хватает. Может быть, я даже усложняю это. Есть ли более простой / лучший способ написать конструкторы перемещения / копирования и операторы присваивания? Вы можете заметить здесь что-нибудь странное? Мне кажется, это нормально ...
Спасибо!
РЕДАКТИРОВАТЬ: я сейчас попытался изменить оператор назначения копирования, как это предложено @eerorika, но мои +
и +=
операторы до сих пор не работает (так же, как и раньше). Просто чтобы быть уверенным, я тогда также попытался отредактировать свой оператор присваивания перемещения и конструктор перемещения таким же образом, как я редактировал свой оператор присваивания копии и до сих пор ... ничего. Вот отредактированные версии
// Move constructor
template <class T>
Matrix<T>::Matrix(Matrix&& obj)
: m_rows(0)
, m_cols(0)
, m_capacity(0)
, m_vec(nullptr)
{
this->m_rows = obj.get_rows();
this->m_cols = obj.get_cols();
this->m_capacity = obj.get_capacity();
//m_vec = obj.m_vec;
this->m_vec = new T[obj.get_rows() * obj.get_cols()];
for (int i = 0; i < obj.get_rows(); i++) {
for (int j = 0; j < obj.get_cols(); j++) {
this->m_vec[j + i * obj.get_cols()] = obj.m_vec[i * this->m_cols + j];
}
}
obj.m_rows = 0;
obj.m_cols = 0;
obj.m_capacity = 0;
obj.m_vec = nullptr;
}
// Move assigment operator
template <class T>
Matrix<T>& Matrix<T>::operator=(Matrix&& obj)
{
// If the address of the object being passed in is the same as "this", do nothing.
if (this != &obj)
{
delete[] m_vec;
this->m_rows = obj.get_rows();
this->m_cols = obj.get_cols();
this->m_capacity = obj.get_capacity();
//m_vec = obj.m_vec;
this->m_vec = new T[obj.get_rows() * obj.get_cols()];
for (int i = 0; i < obj.get_rows(); i++) {
for (int j = 0; j < obj.get_cols(); j++) {
this->m_vec[j + i * obj.get_cols()] = obj.m_vec[i * this->m_cols + j];
}
}
obj.m_rows = 0;
obj.m_cols = 0;
obj.m_capacity = 0;
obj.m_vec = nullptr;
}
return *this;
}
// Copy assignment operator
template <class T>
Matrix<T>& Matrix<T>::operator=(Matrix& obj)
{
this->m_rows = obj.get_rows();
this->m_cols = obj.get_cols();
this->m_capacity = obj.get_capacity();
//m_vec = obj.m_vec;
this->m_vec = new T[obj.get_rows() * obj.get_cols()];
for (int i = 0; i < obj.get_rows(); i++) {
for (int j = 0; j < obj.get_cols(); j++) {
this->m_vec[j + i * obj.get_cols()] = obj.m_vec[i * this->m_cols + j];
}
}
return *this;
}
Есть идеи, что может быть не так сейчас? Вы уверены, что в моих операторах +
и +=
нет ничего плохого? Справка.
РЕДАКТИРОВАТЬ 2:
По запросу @numzero я добавлю код для operator()
template <class T>
T& Matrix<T>::operator()(unsigned int row, unsigned int col) {
if (row > this->m_rows || col > this->m_cols) {
cerr << "index out of range" << endl;;
}
return this->m_vec[(row - 1) * m_cols + (col - 1)];
}