¿Qué 'const' do en el operador () sobrecarga?
-
23-09-2019 - |
Pregunta
Tengo una base de código, en el que para la clase Matrix, estas dos definiciones están ahí para el operador ()
:
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 que entiendo es que el segundo no devuelve la referencia, pero ¿qué significa const
en la segunda declaración? También cuya función es llamada cuando lo haga mat(i,j)
digamos?
Solución
Qué función se llama depende de si la instancia es const o no. La primera versión le permite modificar la instancia:
Matrix<int> matrix;
matrix(0, 0) = 10;
La sobrecarga de const permite acceso de sólo lectura si tiene una instancia const (referencia) de la Matriz:
void foo(const Matrix<int>& m)
{
int i = m(0, 0);
//...
//m(1, 2) = 4; //won't compile
}
El segundo no devuelve una referencia ya que la intención es no permitir la modificación del objeto (se obtiene una copia del valor y por lo tanto no puede modificar la instancia de matriz).
Aquí T se supone que es un simple tipo numérico que es barato (er) para volver por valor. Si T también podría ser una más compleja tipo definido por el usuario, sino que también sería común para sobrecargas const para devolver una referencia constante:
template <class T>
class MyContainer
{
//..,
T& operator[](size_t);
const T& operator[](size_t) const;
}
Otros consejos
La versión const se llamará en const matrices. Por no constante matrices de la versión no const se llamará.
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
}
Qué función se llama depende de si el objeto es const
. Para los objetos de const
sobrecarga const
se llama:
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 mismo se aplica a los punteros. Si la llamada se realiza a través de una constante puntero a una sobrecarga de const se llama. De lo contrario una sobrecarga no constante se llama.