2010-06-18 5 views
12

Je suis très confus au sujet de la version const et la version non-const fonction membre comme ci-dessous:Quelle est la différence entre une fonction membre const et une fonction membre non-const?

value_type& top() { return this.item } 
const value_type& top() const { return this.item } 

Quelle est la différence entre ces deux fonctions? Dans quelle situation seraient-ils utilisés?

+1

Vous devriez envisager d'obtenir l'un des excellents livres d'introduction énumérés dans [Le Guide du livre définitif C++ et Liste] (http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). –

+1

Nitpick: 'mutable' est un mot-clé C++ avec sa propre signification et n'est pas simplement le contraire de' const'. Votre question serait plus claire: "Quelle est la différence entre une fonction membre const et une fonction membre non-const?" –

+1

@Josh - bon point sur la désambiguïsation explicite, mais je pense que 'mutable' est une description assez courante, dans les langages de programmation, de 'quelque chose que vous pouvez modifier'. – Stephen

Répondre

15

En bref, ils sont utilisés pour ajouter 'const correctness' à votre programme.

value_type& top() { return this.item } 

Il est utilisé pour fournir un accès à mutable item. Il est utilisé pour que vous puissiez modifier l'élément dans le conteneur.

Par exemple:

c.top().set_property(5); // OK - sets a property of 'item' 
cout << c.top().get_property(); // OK - gets a property of 'item' 

Un exemple commun pour ce modèle est de retour un accès mutable à un élément avec vector::operator[int index].

std::vector<int> v(5); 
v[0] = 1; // Returns operator[] returns int&. 

D'autre part:

const value_type& top() const { return this.item } 

Il est utilisé pour fournir l'accès à constitem. C'est plus restrictif que la version précédente - mais il a un avantage - vous pouvez l'appeler sur un objet const.

void Foo(const Container &c) { 
    c.top(); // Since 'c' is const, you cannot modify it... so the const top is called. 
    c.top().set_property(5); // compile error can't modify const 'item'. 
    c.top().get_property(); // OK, const access on 'item'. 
} 

Pour suivre l'exemple de vecteur:

const std::vector<int> v(5, 2); 
v[0] = 5; // compile error, can't mutate a const vector. 
std::cout << v[1]; // OK, const access to the vector. 
6

La fonction membre const-qualifiée sera appelée si la fonction membre est appelée sur un objet const-qualifié.

La fonction membre non const-qualifiée sera appelée si la fonction membre est appelée sur un objet qui n'est pas const-qualifié.

Par exemple:

MyStack s; 
s.top(); // calls non-const member function 

const MyStack t; 
t.top(); // calls const member function 

Notez que les mêmes règles sont applicables lors de l'appel d'une fonction de membre d'une référence à un objet ou par un pointeur vers un objet: si le pointeur ou la référence à un objet const, la fonction membre const sera appelée; sinon, la fonction de membre non-const sera appelée.

+0

S'il y a une fonction memeber comme value_type & top() const {return this.item}, un objet non-const peut-il l'appeler? Si ajouter const comme la fonction foo() const, cela signifie que cela changerait l'objet courant, est-ce exact? Si c'est le cas, il devrait être appelé par un objet non const ou const. Est ce bien? –

+0

Si un objet n'est pas const et qu'il y a des surcharges const et non-const d'une fonction membre (et que ces surcharges sont par ailleurs identiques), alors la fonction membre non-const sera appelée. Vous pouvez "forcer" la fonction membre const à appeler en lançant l'objet dans une référence const, puis en appelant la fonction membre sur celle-ci. Une fonction membre const ne peut pas modifier les membres non mutables de l'objet ni ne peut appeler des fonctions membres non const. –

+0

@Yongwei Xing, pour ajouter à la réponse de James, si vous ne donnez qu'une surcharge "const", il sera utilisé par les objets const et non-const. C'est seulement si vous avez une surcharge const et non-const, où ils vont utiliser des versions différentes. En général, si quelque chose peut être déclaré "const", alors il devrait être ... les objets non-const peuvent appeler les fonctions const et non-const, alors que les objets const peuvent seulement appeler des fonctions membres const-qualifiées. –

4

Si vous avez

class Foo 
{ 
    value_type& top() { return this.item } 
    const value_type& top() const { return this.item } 
} 

Si vous avez

Foo foo; 
const Foo cfoo; 

Les types de retour lorsque vous appelez top() sont les suivantes:

value_type& bar = foo.top(); 
const value_type& cbar = cfoo.top(); 

En d'autres termes - si vous avez un instance constante de votre classe, la version const de la fonction est choisie comme surcharge à appeler. La raison de ceci (dans ce cas particulier) est que vous pouvez donner des références à des membres (comme item dans ce cas) à partir d'une instance const d'une classe, et vous assurer qu'ils sont eux aussi constables et donc non modifiables. donc en préservant la constance de l'instance dont ils sont issus.

0

Lorsque la fonction membre est déclaré comme const ce qui se passe est que le paramètre pointeur this implicite passé à la fonction est typé pour être un pointeur vers un objet const . Cela permet d'appeler la fonction en utilisant une instance d'objet const.

value_type& top(); // this function cannot be called using a `const` object 
const value_type& top() const; // this function can be called on a `const` object 
0

value_type& top() { return this.item; } veille à ce que ce soit les membres de l'objet appelant de données peuvent être modifiées ou la valeur de retour peut être.

value_type& top() const { return this.item; } garantit que les membres de données de l'objet appelant ne peuvent pas être modifiés, mais la valeur de retour peut être. Ainsi, par exemple, si j'effectue value_type item_of_x = x.top();, item_of_x peut être modifié mais x ne peut pas. Sinon, une erreur de compilation se produit (comme avoir le code this.item = someValue; à l'intérieur du corps de la fonction).

const value_type& top() { return this.item; } garantit que les membres de l'objet appelant sont autorisés à être modifiés, mais que la valeur de retour ne peut pas l'être. C'est le contraire de ce qui est discuté ci-dessus: si j'effectue const value_type item_of_x = x.top();, item_of_x ne peut pas être modifié mais x peut. NOTEvalue_type item_of_x = x.top(); permet toujours la modification de item_of_x, car item_of_x est maintenant non-const.

const value_type& top() const { return this.item; } garantit que ni les membres de données de l'objet appelant peuvent être modifiés ni la valeur de retour peut être.

Questions connexes