C++模板拷贝构造函数,编译器说"传递const作为此参数丢弃限定符"

Dav*_*vid 4 c++ templates compiler-errors operator-overloading copy-constructor

我正在尝试创建动态矩阵的模板类.凭借我目前对C++的了解,我设法解决了一些问题,但我坚持使用复制构造函数并重载operator =; 换句话说,我无法创建我的对象的副本.在我oppinion这应该工作,但我的朋友,编译器,告诉我,我有1错误:错误:通过"常量矩阵"作为"这个"的"廉政矩阵参数:: getElement(INT,INT)与T = INT ]'在此行丢弃限定符[-fpermissive]:

m[i][j] = original.getElement(i, j);
Run Code Online (Sandbox Code Playgroud)

当我想创建一个对象时:

Matrix<int> m = Matrix<int>(3, 3);
Run Code Online (Sandbox Code Playgroud)

我的模板类在这里:

template<class T>class Matrix
{
 public:

  Matrix<T>(int lines, int columns)
  {
    this->lines = lines;
    this->columns = columns;
    T* aux = new T[this->lines * this->columns];
    m = new T*[lines];
    for (int i = 0; i < this->lines; i++)
    {
      m[i] = aux + (i * this->columns);
    }
    for (int i = 0; i < this->lines; i++)
    {
      for (int j = 0; j < this->columns; j++)
      {
        m[i][j] = 0;
      }
    }
  }

  Matrix<T>(const Matrix<T>& original)
  {
    columns = original.getColumns();
    lines = original.getLines();
    T* aux = new T[this->lines * this->columns];
    m = new T*[lines];
    for (int i = 0; i < lines; i++)
    {
      m[i] = aux + (i * this->columns);
    }
    for (int i = 0; i < lines; i++)
    {
      for (int j = 0; j < columns; j++)
      {
        m[i][j] = original.getElement(i, j);
      }
    }
  }

  virtual ~Matrix<T>()
  {
    /*for (int i = lines - 1; i > 0; i--)
    {
      delete m[i];
    }*/
    delete [] m;
  }

  T** getPointer()
  {
    return m;
  }

  int getLines () const
  {
    return lines;
  }

  int getColumns () const
  {
    return columns;
  }

  int getElement(int line, int column)
  {
    return m[line][column];
  }

  int setElement(int line, int column, T value)
  {
    m[line][column] = value;
  }

  Matrix<T>* getTranspose()
  {
    Matrix<T>* aux = new Matrix<T>(lines, columns);
    for (int i = 0; i < lines; i++)
    {
      for (int j = 0; j < columns; j++)
      {
        aux->setElement(i,j, m[j][i]);
      }
    }
    return aux;
  }

  Matrix<T> operator=(const Matrix<T> original)
  {
    columns = original.getColumns();
    lines = original.getLines();
    T* aux = new T[this->lines * this->columns];
    m = new T*[lines];
    for (int i = 0; i < lines; i++)
    {
      m[i] = aux + (i * this->columns);
    }
    for (int i = 0; i < lines; i++)
    {
      for (int j = 0; j < columns; j++)
      {
        m[i][j] = original.getElement(i, j);
      }
    }
  }

  friend std::ostream& operator<<(std::ostream& out, Matrix<T>& matrix)
  {
    out<<"Matrix:"<<std::endl;
    for (int i = 0; i < matrix.getLines(); i++)
    {
      for (int j = 0; j < matrix.getColumns(); j++)
      {
        out<<matrix.getElement(i, j)<<" ";
      }
      out<<std::endl;
    }
    return out;
  }

  friend std::istream& operator>>(std::istream& in, Matrix<T>& matrix)
  {
    std::cout << "Reading Matrix:\n";
    for (int i = 0; i < matrix.getLines(); i++)
    {
      for (int j = 0; j < matrix.getColumns(); j++)
      {
        std::cout << "Matrix[" << i << "][" << j << "]:";
        in >> matrix.m[i][j];
      }
      std::cout << std::endl;
    }
    return in;
  }

 private:
  T** m;
  int lines;
  int columns;
};
Run Code Online (Sandbox Code Playgroud)

正如我可以从该错误中弄清楚我正在创建2个对象,这些对象引用相同的内存块,但我想创建2个对象,这些对象引用具有相同内容的2个不同内存块.

jog*_*pan 10

在你的拷贝构造函数中

Matrix<T>(const Matrix<T>& original)
Run Code Online (Sandbox Code Playgroud)

original被声明为const引用,这非常好.但是,这意味着您不能调用任何Matrix<T>未声明为const函数的方法.

getElement函数未声明为,const因此您无法在复制构造函数中使用它.通过将其声明为const函数来解决此问题:

int getElement(int line, int column) const  // <--- Note the 'const'
{
  return m[line][column];
}
Run Code Online (Sandbox Code Playgroud)

这意味着:

  1. 可以在Matrixconst对象上调用此函数(例如original在复制构造函数中)

  2. 您无法执行任何getElement修改当前实例Matrix(即修改*this)的操作.

前者是我们想要的,而后者不是问题,因为getElement它只是一个getter方法,所以它不需要修改任何东西.

请注意,因此,始终将成员函数标记为const不应修改任何内容时是个好主意.这意味着您可以将它们应用于常量对象,这意味着编译器会告诉您是否错误地将代码放入实际修改某些内容的函数中.

最后评论:正如Tore Olsen所指出的,getElement函数应该返回一个对象或类型的引用T而不是int.