派生类运算符=错误

时间:2015-09-15 18:41:13

标签: c++ operator-keyword instantiation derived-class

编译以下代码时出错。我想基本上创建一个名为SqMatrix的派生类,方形矩阵,作为Matrix的派生类型。但是,编译器不会让我实例化一些自定义运算符。以下是我的代码matrix.h

#ifndef matrix_h
#define matrix_h

#include <string>
#include <vector>
#include <typeinfo>

template<class T>
class Matrix {
private:
  size_t nrow;
  size_t ncol;
  std::string typenm;
  std::vector<T> *vec;
public:
  Matrix(): nrow(0), ncol(0), vec(), typenm("") {}
  Matrix(size_t nr, size_t nc, T value=T()): nrow(nr), ncol(nc), typenm(std::string(typeid(T).name()))
  { vec = new std::vector<T>(nrow*ncol, value); }
  ~Matrix()
  { delete vec; }
  size_t getnrow() const
  { return nrow; }
  size_t getncol() const
  { return ncol; }
  std::string gettypenm() const
  { return typenm; }
  T *getdata()
  { return vec->data(); }
  T *getdata() const
  { return vec->data(); }
  T &at(size_t ir, size_t ic)
{ return vec->at(ic*nrow+ir); }
  T &at(size_t ir, size_t ic) const
  { return vec->at(ic*nrow+ir); }
  virtual void resize(size_t nr, size_t nc, T value=T())
  {
    vec->resize(nr*nc, value);
    nrow = nr;
    ncol = nc;
  }
  Matrix &operator =(const Matrix &mat);
  Matrix operator +(const Matrix &mat) const;
  Matrix operator -(const Matrix &mat) const;
};

template<class T>
class SqMatrix: public Matrix<T> {
private:
  size_t ndim;
public:
  SqMatrix(): Matrix<T>(), ndim(0) {}
  SqMatrix(size_t nd, T value=T()): Matrix<T>(nd, nd, value), ndim(nd) {}
  size_t getndim() const
  { return ndim; }
  virtual void resize(size_t nd, T value=T())
  {
    Matrix<T>::resize(nd, nd, value);
    ndim = nd;
  }
  SqMatrix &operator =(const SqMatrix &sqmat)
  {
    Matrix<T>::operator =(sqmat);
    return *this;
  }
};

#endif

然后我执行方法,matrix.cpp

#include <iostream>
#include <cstring>
#include <string>
#include <typeinfo>
#include "precision.h"
#include "matrix.h"
#include "lapack.h"

template<class T>
Matrix<T> &Matrix<T>::operator =(const Matrix<T> &mat)
{
  try {
    if(nrow != mat.nrow) throw "Matrix::operator =: Invalid mat.nrow";
    if(ncol != mat.ncol) throw "Matrix::operator =: Invalid mat.ncol";
  }
  catch(const char *str) {
    std::cout << str << std::endl;
  }

  memcpy(vec->data(), mat.vec->data(), sizeof(T)*nrow*ncol);

  return *this;
}

template<class T>
Matrix<T> Matrix<T>::operator +(const Matrix<T> &mat) const
{
  try {
    if(nrow != mat.nrow) throw "Matrix::operator +: Invalid mat.nrow";
    if(ncol != mat.ncol) throw "Matrix::operator +: Invalid mat.ncol";
  }
  catch(const char *str) {
    std::cout << str << std::endl;
  }

  Matrix<T> matsum(nrow, ncol);

  for(size_t i = 0; i < nrow*ncol; ++i)
    matsum.vec->at(i) = vec->at(i) + mat.vec->at(i);

  return matsum;
}

template<class T>
Matrix<T> Matrix<T>::operator -(const Matrix<T> &mat) const
{
  try {
    if(nrow != mat.nrow) throw "Matrix::operator -: Invalid mat.nrow";
    if(ncol != mat.ncol) throw "Matrix::operator -: Invalid mat.ncol";
  }
  catch(const char *str) {
    std::cout << str << std::endl;
  }

  Matrix<T> matdif(nrow, ncol);

  for(size_t i = 0; i < nrow*ncol; ++i)
    matdif.vec->at(i) = vec->at(i) - mat.vec->at(i);

  return matdif;
}

template Matrix<dreal> &Matrix<dreal>::operator =(const Matrix<dreal> &);
template Matrix<dreal> Matrix<dreal>::operator +(const Matrix<dreal> &) const;
template Matrix<dreal> Matrix<dreal>::operator -(const Matrix<dreal> &) const;

template Matrix<dcmplx> &Matrix<dcmplx>::operator =(const Matrix<dcmplx> &);
template Matrix<dcmplx> Matrix<dcmplx>::operator +(const Matrix<dcmplx> &) const;
template Matrix<dcmplx> Matrix<dcmplx>::operator -(const Matrix<dcmplx> &) const;

最后它是主要代码test.cpp

#include <iostream>
#include <typeinfo>
#include "constants.h"
#include "matrix.h"

using namespace std;
using namespace constants;

int main()
{
  const size_t Ndim(7);
  SqMatrix<dreal> sqmatA(Ndim,Ndim), sqmatB(Ndim,Ndim), sqmatC(Ndim,Ndim);

  for(size_t i = 0; i < Ndim; ++i)
    for(size_t j = 0; j < Ndim; ++j) {
      sqmatA.at(j, i) = (i+1) * (j+1);
      sqmatB.at(j, i) = i + j;
    }

  sqmatC = sqmatA + sqmatB;

  return 0;
}

编译器抱怨说这很奇怪:

test.cpp: In function ‘int main()’:
test.cpp:20: error: no match for ‘operator=’ in ‘sqmatC = Matrix<T>::operator+(const Matrix<T>&) const [with T = double](((const Matrix<double>&)((const Matrix<double>*)(& sqmatB.SqMatrix<double>::<anonymous>))))’
matrix.h:62: note: candidates are: SqMatrix<T>& SqMatrix<T>::operator=(const SqMatrix<T>&) [with T = double]

显然,这是由于operator =派生类SqMatrix。我实际上为SqMatrix实现了operator =,为什么它仍然抱怨,或者我犯的实际错误是什么?

提前致谢!

2 个答案:

答案 0 :(得分:0)

您的子类operator+中缺少SqMatrix。这就是为什么您的矩阵总和sqmatA + sqmatB使用泛型类operator+的{​​{1}},它返回Matrix,因此无法传递给您的特定{您的子类Matrix中的{1}}。

答案 1 :(得分:0)

编译错误:

'+'运算符返回类'Matrix'的对象。您没有在'SqMatrix'中定义一个带有'Matrix'对象的赋值运算符。

总而言之,将方矩阵作为矩阵的子类可能是也可能不是最好的想法:

  • 你带有一个多余的成员变量(ndim)而不是方形矩阵是维度和数据,它的维度,数据和继承的x和y维度
  • 没有矩阵重载的方法来利用矩形
  • 你创造了歧义 - 可以创建一个正方形的矩阵(因为它恰好具有相同的x&amp; y维度)

作为矩阵是更好的套件,可以作为矩阵的(计算)属性。