[英]C++ template copy constructor, compiler says “passing const as this argument discards qualifiers”
我正在嘗試創建動態矩陣的模板類。 憑借我目前對C ++的了解,我設法解決了一些問題,但我堅持使用復制構造函數並重載operator =; 換句話說,我無法創建我的對象的副本。 在我的意見中,這應該有效,但是我的朋友,編譯器,告訴我有1個錯誤:錯誤:將'const Matrix'作為'int'的參數傳遞給'int Matrix :: getElement(int,int)[與T = int ]'在此行丟棄限定符[-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引用,這非常好。 但是,這意味着您不能在其上調用任何未聲明為const
函數的Matrix<T>
方法。
getElement
函數未聲明為const
因此您無法在復制構造函數中使用它。 通過將其聲明為const函數來解決此問題:
int getElement(int line, int column) const // <--- Note the 'const'
{
return m[line][column];
}
這意味着:
可以在const對象的Matrix
對象上調用此函數(例如復制構造函數中的original
對象)
您無法在getElement
中執行任何修改Matrix
當前實例的操作(即修改*this
)。
前者是我們想要的,后者不是問題因為getElement
只是一個getter方法,所以它不需要修改任何東西。
請注意,因此,當它們不應該修改任何內容時, 始終將成員函數標記為const
是個好主意。 這意味着您可以將它們應用於常量對象,這意味着編譯器會告訴您是否錯誤地將代碼放入實際修改某些內容的函數中。
最后評論:正如Tore Olsen所指出的, getElement
函數應該返回類型為T
而不是int
的對象或引用。
正如我常說的那樣,當你開始編寫const
,你無法停止直到結束。 因為const對象可以使用const方法而只能使用const方法。 但是,const-correctness對於C ++程序員來說很重要。 我讀過一篇關於那篇的文章,不幸的是它是用法語寫的,但我認為用英語很容易找到。 它解釋了const-correctness為您的程序帶來安全性和安全性。 它有助於一些優化,但在這里我不記得作者的觀點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.