2010-06-15 15 views
1

auto_ptr on wikipedia a déclaré que "un auto_ptr contenant un conteneur STL peut être utilisé pour empêcher toute modification supplémentaire du conteneur.". Il a utilisé l'exemple suivant:Pourquoi un auto_ptr peut "sceller" un conteneur

auto_ptr<vector<ContainedType> > open_vec(new vector<ContainedType>); 

open_vec->push_back(5); 
open_vec->push_back(3); 

// Transfers control, but now the vector cannot be changed: 
auto_ptr<const vector<ContainedType> > closed_vec(open_vec); 

// closed_vec->push_back(8); // Can no longer modify 

Si je décommenter la dernière ligne, g ++ signale une erreur

t05.cpp:24: error: passing ‘const std::vector<int, std::allocator<int> >’ 
as ‘this’ argument of ‘void std::vector<_Tp, _Alloc>::push_back(const _Tp&) 
[with _Tp = int, _Alloc = std::allocator<int>]’ discards qualifiers 

Je suis curieux de savoir pourquoi après le transfert de la propriété de ce vecteur, il ne peut plus être modifié?

Merci beaucoup!

Répondre

4

Le pointeur closed_vec contient le type const vector<ContainedType>. Comme le type est const, vous ne pouvez pas appeler de méthodes qui ne sont pas définies comme const (ce qui signifie qu'elles ne modifient pas les données internes). Naturellement push_back est non-const, car il change le vecteur, donc vous ne pouvez pas l'appeler sur un pointeur const. Il n'a pas vraiment rien à voir avec auto_ptr, vous pouvez accomplir la même chose avec des pointeurs réguliers:

vector<ContainedType>* open_vec = new vector<ContainedType>(); 
open_vec->push_back(5); 
open_vec->push_back(3); 

const vector<ContainedType>* closed_vec = open_vec; 
closed_vec->push_back(8); // Fails 
+0

Merci beaucoup! :) J'ai négligé le "const" dans closed_vec. – icephere

+3

Il _does_ a quelque chose à voir avec auto_ptr. Avec des pointeurs réguliers, l'ancien pointeur non const peut toujours être utilisé pour modifier le conteneur. Le auto_ptr non const sera NULL après le transfert de propriété. – MSalters

1

Vous ne pouvez pas modifier le vecteur parce closed_vec est un pointeur à const, de sorte que le won du compilateur » t vous permet de modifier le pointeur (mais vous pouvez toujours déplacer le pointeur). Pour permettre la modification du vecteur, déclarer closed_vec comme

auto_ptr<vector<ContainedType> > closed_vec(open_vec); // no const anymore 
closed_vec->push_back(8); // this now works 

Si vous aviez déclaré le pointeur comme

const auto_ptr<vector<ContainedType> > closed_vec(open_vec); 

d'autre part, vous seriez en mesure de changer le pointée, mais pas déplace le pointeur.