Qu'est-ce que « const » faire dans l'opérateur () surcharge?
-
23-09-2019 - |
Question
J'ai une base de code, dans lequel la classe Matrix, ces deux définitions sont là pour l'opérateur de ()
:
template <class T> T& Matrix<T>::operator() (unsigned row, unsigned col)
{
......
}
template <class T> T Matrix<T>::operator() (unsigned row, unsigned col) const
{
......
}
Une chose que je comprends est que le second ne renvoie pas la référence, mais qu'est-ce que const
signifie dans la deuxième déclaration? Aussi dont la fonction est appelée lorsque je dis mat(i,j)
?
La solution
Quelle fonction est appelée dépend si l'instance est const ou non. La première version permet de modifier l'instance:
Matrix<int> matrix;
matrix(0, 0) = 10;
La surcharge const permet un accès en lecture seule si vous disposez d'une instance const (référence) de la matrice:
void foo(const Matrix<int>& m)
{
int i = m(0, 0);
//...
//m(1, 2) = 4; //won't compile
}
Le second ne renvoie pas de référence puisque l'intention est d'interdire la modification de l'objet (vous obtenez une copie de la valeur et ne peut donc pas modifier l'instance de la matrice).
Ici T est censé être un type numérique simple qui ne coûte pas cher (er) pour retourner en valeur. Si T peut aussi être un type défini par l'utilisateur plus complexe, il serait également courant pour const de retourner les surcharges une référence const:
template <class T>
class MyContainer
{
//..,
T& operator[](size_t);
const T& operator[](size_t) const;
}
Autres conseils
La version const sera appelée sur const Matrices. Sur la non-const matrices la version non-const sera appelée.
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
}
Quelle fonction est appelée dépend si l'objet est const
. Pour les objets const
surcharge const
est appelé:
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
de même pour les pointeurs. Si l'appel est effectué au moyen d'un pointeur sur const, une surcharge const est appelée. Dans le cas contraire une surcharge non-const est appelée.