2010-03-30 4 views
3

J'ai une base de code, dans lequel la classe Matrix, ces deux définitions sont là pour () opérateur:Que fait 'const' dans la surcharge operator()?

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 en la deuxième déclaration? Aussi quelle fonction est appelée quand je dis mat(i,j)?

+1

Le modificateur const sur les forces de fonction compilateur pour vérifier que la fonction ne modifie pas l'état de classe ou permet de changer d'état de classe (en passant des références/pointeurs ou en utilisant des fonctions non-const). –

Répondre

6

dont la 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 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 fonctionne pas renvoyer une 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 de surcharge const de retourner une référence const:

template <class T> 
class MyContainer 
{ 
     //.., 
     T& operator[](size_t); 
     const T& operator[](size_t) const; 
} 
1

Quelle fonction est appelée dépend si l'objet est const. Pour const objets const surcharge 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 fait via un pointeur-à-const, une surcharge const est appelée. Sinon, une surcharge non-const est appelée.

3

La version const sera appelée sur les matrices const. Sur 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 
} 
+0

+1, en ajoutant un exemple avec une référence constante à un objet non-const peut aussi aider, comme dans la plupart des cas, les objets eux-mêmes ne sont pas constants, mais les fonctions obtenir/retour des références constantes à des objets non-const. –

+0

Je pense que vous avez "premier/deuxième" faux dans les commentaires premier et deuxième. (sauf si OP a changé l'ordre de définition). –

+0

@Pasi - je ne sais pas comment c'est arrivé. Je pensais avoir vérifié cela. J'ai changé la description pour résister à la réorganisation dans l'OP maintenant. –