我正在尝试创建动态矩阵的模板类。凭借我目前对 C++ 的了解,我设法解决了一些问题,但我被复制构造函数和重载 operator=; 困住了。换句话说,我无法创建对象的拷贝。 在我看来这应该可行,但我的编译器 friend 告诉我有 1 个错误: 错误:将“const Matrix”作为“int Matrix::getElement(int, int) [with T = int]”的“this”参数传递会丢弃此行的限定符 [-fpermissive]:
m[i][j] = original.getElement(i, j);
当我想创建一个对象时:
Matrix<int> m = Matrix<int>(3, 3);
我的模板类在这里:
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;
};
我可以从那个错误中弄清楚,我正在创建 2 个对象,它们引用相同的内存块,但我想创建 2 个对象,它们引用 2 个具有相同内容的不同内存块。
最佳答案
在你的复制构造函数中
Matrix<T>(const Matrix<T>& original)
original
被声明为 const 引用,这非常好。但是,这意味着您不能调用 Matrix<T>
的任何方法。在其上未声明为 const
功能。
getElement
函数未声明为 const
所以你不能在复制构造函数中使用它。通过将其声明为常量函数来解决此问题:
int getElement(int line, int column) const // <--- Note the 'const'
{
return m[line][column];
}
这意味着:
这个函数可以在
Matrix
上调用const 对象(例如复制构造函数中的original
)您不能在
getElement
中执行任何操作修改Matrix
的当前实例(即修改*this
)。
前者是我们想要的,后者不是问题,因为getElement
只是一个getter方法,所以它不需要修改任何东西。
请注意,因此,始终 将成员函数标记为 const
是个好主意当他们不应该修改任何东西时。这意味着您可以将它们应用于常量对象,这意味着编译器会告诉您是否错误地将代码放入实际上确实修改了某些内容的函数中。
最后的评论:正如 Tore Olsen 所指出的,getElement
函数应该返回类型为 T
的对象或引用而不是 int
.
关于C++ 模板复制构造函数,编译器说 "passing const as this argument discards qualifiers",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12929014/