Cosa significa 'const' fare dell'operatore () sovraccarico?
-
23-09-2019 - |
Domanda
Ho una base di codice, in cui per la classe Matrix, queste due definizioni ci sono per l'operatore ()
:
template <class T> T& Matrix<T>::operator() (unsigned row, unsigned col)
{
......
}
template <class T> T Matrix<T>::operator() (unsigned row, unsigned col) const
{
......
}
Una cosa che ho capito è che la seconda non restituisce il riferimento ma cosa significa const
nella seconda dichiarazione? Inoltre cui funzione viene chiamata quando lo dico mat(i,j)
?
Soluzione
Quale funzione viene chiamata dipende dal fatto che l'istanza è const o meno. La prima versione consente di modificare l'istanza:
Matrix<int> matrix;
matrix(0, 0) = 10;
Il sovraccarico const consente accesso in sola lettura se si dispone di un'istanza const (di riferimento) di Matrix:
void foo(const Matrix<int>& m)
{
int i = m(0, 0);
//...
//m(1, 2) = 4; //won't compile
}
Il secondo non restituisce un riferimento in quanto l'intenzione è quella di impedire modificare l'oggetto (si ottiene una copia del valore e quindi non può modificare l'istanza matrice).
Qui T dovrebbe essere un semplice tipo numerico che è economico (er) per tornare al valore. Se T potrebbe anche essere un tipo definito dall'utente più complesso, sarebbe anche comune per sovraccarichi const per restituire un riferimento const:
template <class T>
class MyContainer
{
//..,
T& operator[](size_t);
const T& operator[](size_t) const;
}
Altri suggerimenti
La versione const sarà chiamato su matrici const. Sulla non-const matrici la versione non-const sarà chiamato.
Matrix<int> M;
int i = M(1,2); // Calls non-const version since M is not const
M(1,2) = 7; // Calls non-const version since M is not const
const Matrix<int> MConst;
int j = MConst(1,2); // Calls const version since MConst is const
MConst(1,2) = 4; // Calls the const version since MConst is const.
// Probably shouldn't compile .. but might since return value is
// T not const T.
int get_first( const Matrix<int> & m )
{
return m(0,0); // Calls the const version as m is const reference
}
int set_first( Matrix<int> & m )
{
m(0,0) = 1; // Calls the non-const version as m is not const
}
Quale funzione viene chiamata dipende dal fatto che l'oggetto è const
. Per gli oggetti const
sovraccarico const
si chiama:
const Matrix<...> mat;
const Matrix<...>& matRef = mat;
mat( i, j);//const overload is called;
matRef(i, j); //const overloadis called
Matrix<...> mat2;
mat2(i,j);//non-const is called
Matrix<...>& mat2Ref = mat2;
mat2Ref(i,j);//non-const is called
const Matrix<...>& mat2ConstRef = mat2;
mat2ConstRef(i,j);// const is called
Lo stesso vale per i puntatori. Se la chiamata viene effettuata tramite un puntatore a const, un sovraccarico const viene chiamato. In caso contrario, un sovraccarico di non-const viene chiamato.