矩阵模板类

时间:2019-12-09 23:26:13

标签: c++ templates matrix

程序template <class T> const Matrix<T> &Matrix<T>::operator*=(T rhs)的方法matrix.cc应该能够返回调用矩阵为rhs缩放的调用对象,并且参数rhs将与矩阵具有相同的类型。

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

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

有人知道我通过// TEST MUL ASSIGMENT OP CORRECT RETURN部分时,是否可以让我知道为什么收到此“失败”输出。

这是我的matrix.cc:

#include <matrix.h>

template <class T>
const Matrix<T> &Matrix<T>::operator*=(T rhs) {
  unsigned int rows_ = 0;
  unsigned int cols_ = 0;
  T **m_ = nullptr;

  for (unsigned int i = 0; i < rows_; ++i) {
    m_[i] = new T[cols_];
    for (unsigned int j = 0; j < cols_; ++j) {
      m_[i][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] += rhs[i];
    }
  }
  return lhs;
}

这是我的矩阵。h:

#include <cassert>
// using assert
#include <exception>
#include <iostream>

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

  /* Times Equals Op: 1 Point
   *   Returns calling object with matrix scaled by rhs.
   *   Parameter:
   *    - rhs will be the same type as the matrix
   */
  const Matrix<T> &operator*=(T rhs);

  /* Add Op: 1 Point
   *   Returns the sum of calling object's matrix and rhs's matrix as a new
   *   object.
   * Precondition(s):
   *   - lhs rows must equal rhs rows
   *   - lhs cols must equal rhs cols
   */
  const Matrix<T> operator+(const Matrix<T> &rhs) const;

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

#include <matrix.cc>  //NOLINT

这是我的test_matrix_mul_assign.cc测试人员:

#include <test_matrix.h>

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

  cout << "Testing Matrix::operator*=" << endl;
  if (tester.Test_MulAssignOp()) {
    cout << "  PASSED" << endl;
    return 0;
  }

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

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

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

  // TEST MUL ASSIGMENT OP CORRECT RETURN
  const Matrix<double> *m_ptr = &(test_m *= 2.0);
  if (m_ptr != &test_m) {
    cout << "  Expected return address of assigment: " << &test_m
         << ", Actual: " << m_ptr << endl;
    return false;
  }
  // TEST MUL ASSIGMENT OP CALCULATION
  if (test_m.m_[0][0] != 2.0) {
    cout << "  Expected Matrix[0][0]: 2.0, Actual: " << test_m.m_[0][0] << endl;
    return false;
  }
  if (test_m.m_[1][3] != 16.0) {
    cout << "  Expected Matrix[1][3]: 16.0, Actual: " << test_m.m_[1][3]
         << endl;
    return false;
  }
  if (test_m.m_[2][2] != 18.0) {
    cout << "  Expected Matrix[2][2]: 18.0, Actual: " << test_m.m_[2][2]
         << endl;
    return false;
  }
  return true;
}

1 个答案:

答案 0 :(得分:2)

operator*=实现中,您具有以下变量定义:

unsigned int rows_ = 0;
unsigned int cols_ = 0;
T **m_ = nullptr;

他们将遮盖所有班级成员。稍后在函数定义中使用rows_cols_m_时,它们将引用这些局部变量,而不是当前实例的类成员。

因此,有效地执行operator*=根本不执行任何操作。正确值的测试然后失败就不足为奇了。

只需删除这些声明,以便名称将指向当前实例的成员。

然后,m_[i] = new T[cols_];也将毫无意义。因此也将其删除。


为什么首先使用new进行所有这些动态分配?这是严重的不良样式,将导致您遇到各种问题。请改用std::vector


class Matrix似乎也缺少适当的构造函数。这将再次引起各种问题,尤其是当它将内存分配留给该类的用户时。