gpt4 book ai didi

c++ - C++矩阵运算符+

转载 作者:行者123 更新时间:2023-12-02 10:07:54 26 4
gpt4 key购买 nike

程序template <class T> const Matrix<T> Matrix<T>::operator+(const Matrix<T> &rhs) constmatrix.cc方法应该能够返回调用对象矩阵和rhs矩阵的和作为新对象。同样,lhs和rhs行和cols将相等。

我从编译器收到的错误输出是:

[hw7] make clean && make bin/test_add && ./bin/test_add                                           UserSettings  ✱
rm -f bin/*
g++ -std=c++11 -Wall -I inc -I src -c src/test_matrix_add.cc -o bin/test_matrix_add.o
g++ -std=c++11 -Wall -I inc -I src -o bin/test_add bin/test_matrix_add.o
Testing Matrix::operator+
Expected Matrix2[0][0]: 3.0, Actual: 1
FAILED

当我知道我通过 // TEST MUL ASSIGMENT OP CORRECT RETURN节时,有人可以让我知道为什么收到此“失败”输出的原因。

这是我的matrix.cc:
#include <matrix.h>

template <class T>
Matrix<T>::Matrix() {
rows_ = 0;
cols_ = 0;
m_ = nullptr;
}

template <class T>
Matrix<T>::Matrix(unsigned int rows, unsigned int cols)
: rows_(rows), cols_(cols) {
m_ = new T *[rows_];
for (unsigned int i = 0; i < rows_; ++i) {
m_[i] = new T[cols_];
}
}

template <class T>
Matrix<T>::Matrix(const Matrix<T> &that) {
rows_ = that.rows_;
cols_ = that.cols_;
m_ = new T *[rows_];
for (unsigned int i = 0; i < rows_; ++i) {
m_[i] = new T[cols_];
for (unsigned int j = 0; j < cols_; ++j) {
m_[i][j] = that.m_[i][j];
}
}
}

template <class T>
Matrix<T>::~Matrix() {
for (unsigned int i = 0; i < rows_; ++i) {
delete[] m_[i]; // delete columns
}
delete[] m_; // delete columns
}

template <class T>
T Matrix<T>::Get(unsigned int row, unsigned int col) const {
if (row > rows_ && col > cols_) {
throw std::out_of_range("error: index out of range");
}
return this->m_[row][col];
}

template <class T>
const Matrix<T> &Matrix<T>::operator=(const Matrix<T> &rhs) {
if (this == &rhs) {
return *this;
} // returns the address

for (unsigned int i = 0; i < rows_; ++i) {
delete[] m_[i];
}
delete[] m_;

rows_ = rhs.rows_;
cols_ = rhs.cols_;
m_ = new T *[rows_];
for (unsigned int i = 0; i < rows_; ++i) {
m_[i] = new T[cols_];
for (unsigned int j = 0; j < cols_; ++j) {
m_[i][j] = rhs.m_[i][j];
}
}
return *this;
}

template <class T>
const Matrix<T> &Matrix<T>::operator*=(T rhs) {
for (unsigned int i = 0; i < rows_; ++i) {
for (unsigned int j = 0; j < cols_; ++j) {
m_[i][j] *= rhs;
}
}
return *this;
}

template <class T>
const Matrix<T> Matrix<T>::operator+(const Matrix<T> &rhs) const {
if (!(this->cols_ == rhs.cols_) || (this->rows_ == rhs.rows_)) {
std::cout << "Cannont add matrices. Wrong dimensions\n";
exit(0);
}
Matrix<T> lhs;
lhs.rows_ = this->rows_;
lhs.cols_ = this->cols_;
for (unsigned int i = 0; i < lhs.rows_; ++i) {
for (unsigned int j = 0; j < lhs.cols_; ++j) {
lhs[i][j] += rhs[i][j];
}
}
return lhs;
}

这是我的matrix.h:
#include <cassert>
// using assert
#include <exception>
#include <iostream>

template <class T>
class Matrix {
public:
friend class MatrixTester;

Matrix(); // for testing, useless in practice
Matrix(unsigned int rows, unsigned int cols);
Matrix(const Matrix<T> &that);
~Matrix();
T Get(unsigned int row, unsigned int col) const;
const Matrix<T> &operator=(const Matrix<T> &rhs);
const Matrix<T> &operator*=(T rhs);
const Matrix<T> operator+(const Matrix<T> &rhs) const;

private:
T **m_;
unsigned int rows_;
unsigned int cols_;
};

#include <matrix.cc> //NOLINT

这是我的test_matrix_add.cc测试人员:
#include <test_matrix.h>

int main(int argc, char** argv) {
MatrixTester tester;

cout << "Testing Matrix::operator+" << endl;
if (tester.Test_AddOp()) {
cout << " PASSED" << endl;
return 0;
}

cout << " FAILED" << endl;
return 1;
}

bool MatrixTester::Test_AddOp() const {
const int kRows = 4, kCols = 5;
Matrix<double> m1;
m1.m_ = new double*[kRows];
for (unsigned int i = 0; i < kRows; ++i) {
m1.m_[i] = new double[kCols];

for (unsigned int j = 0; j < kCols; ++j)
m1.m_[i][j] = (i + 1.0) * (j + 1.0);
}
m1.rows_ = kRows;
m1.cols_ = kCols;

// TEST ADDITION CORRECTNESS
Matrix<double> m2;
m2 = m1;
// + m1 + m1;
if (m2.m_[0][0] != 3) {
cout << " Expected Matrix2[0][0]: 3.0, Actual: " << m2.m_[0][0] << endl;
return false;
}
if (m2.m_[1][3] != 24.0) {
cout << " Expected Matrix2[1][3]: 24.0, Actual: " << m2.m_[1][3] << endl;
return false;
}
if (m2.m_[2][2] != 27.0) {
cout << " Expected Matrix2[2][2]: 27.0, Actual: " << m2.m_[2][2] << endl;
return false;
}
if (m2.m_[3][4] != 60.0) {
cout << " Expected Matrix2[2][2]: 60.0, Actual: " << m2.m_[2][2] << endl;
return false;
}

return true;
}

最佳答案

首先,这里有太多代码。

为了解决您的问题,我看不到您为lhs.m_分配内存。这是一个问题,因为您使用默认构造函数初始化了lhs,该构造函数仅将this->m_分配给nullptr

要解决此问题,这应该可以工作(尽管未经测试):

template <class T>
const Matrix<T> Matrix<T>::operator+(const Matrix<T>& rhs) const
{
if (!(this->cols_ == rhs.cols_) || (this->rows_ == rhs.rows_))
{
std::cout << "Cannot add matrices. Wrong dimensions\n";
exit(0);
}
Matrix<T> lhs;
lhs.rows_ = this->rows_;
lhs.cols_ = this->cols_;

// Allocate memory for `lhs.m_`, like you did in your 2nd constructor
lhs.m_ = new T* [rows_];
for (unsigned i = 0; i < rows_; ++i)
{
m_[i] = new T[cols_];
}
// [End] allocation

for (unsigned int i = 0; i < lhs.rows_; ++i)
{
for (unsigned int j = 0; j < lhs.cols_; ++j)
{
lhs[i][j] += rhs[i][j];
}
}
return lhs;
}

另外,有些无关,请注意始终将 m_视为双指针。我没有阅读您所有的代码,但要小心。还要记住,您必须在析构函数中释放所有使用 new分配的内存。就个人而言,我认为您应该使用 <memory>(例如 std::unique_ptr等)中的智能指针,您可以了解有关 here的更多信息。使用智能指针将使指针自行分配内存,而您不必担心内存泄漏。

编辑1
正如胡桃木所说,更好的解决方案是只调用第二个构造函数,它将为您分配内存。因此,您修改后的功能将是:

template <class T>
/**
Note:
> When you call this function (e.g. Matrix<T> new_mat = mat1 + mat2),
`mat1` is `this` and `mat2` is what you're calling `rhs`. I've done
some renaming and corrected your logic errors here
*/
const Matrix<T> Matrix<T>::operator+(const Matrix<T>& other) const
{
if (!(this->cols_ == other.cols_) || (this->rows_ == other.rows_))
{
std::cout << "Cannot add matrices. Wrong dimensions\n";
exit(0);
}

// Call the 2nd constructor
Matrix<T> res(this->rows_, this->cols_);

for (unsigned i = 0; i < res.rows_; ++i)
{
for (unsigned j = 0; j < res.cols_; ++j)
{
res.m_[i][j] = this->m_[i][j] + other.m_[i][j];
}
}
return res;
}

编辑2
根据@walnut的注释,以上代码正确正确地添加了矩阵。

关于c++ - C++矩阵运算符+,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59260034/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com