Question

Pourquoi est-il incorrect d'utiliser std :: auto_ptr < > avec des conteneurs standard?

Était-ce utile?

La solution

La norme C ++ indique qu'un élément STL doit être "copy-constructible". et " assignable. " En d'autres termes, un élément doit pouvoir être affecté ou copié et les deux éléments sont logiquement indépendants. std :: auto_ptr ne remplit pas cette condition.

Prenez par exemple ce code:

class X
{
};

std::vector<std::auto_ptr<X> > vecX;
vecX.push_back(new X);

std::auto_ptr<X> pX = vecX[0];  // vecX[0] is assigned NULL.

Pour surmonter cette limitation, vous devez utiliser le std :: unique_ptr , std :: shared_ptr ou std :: faible_ptr un pointeur intelligent ou l'équivalent boost si vous n'avez pas C ++ 11. Voici la documentation de la bibliothèque complémentaire pour ces pointeurs intelligents.

Autres conseils

La sémantique de copie de auto_ptr n'est pas compatible avec les conteneurs.

Spécifiquement, copier un auto_ptr dans un autre ne crée pas deux objets égaux, l'un d'entre eux ayant perdu la propriété du pointeur.

Plus précisément, la copie d'un auto_ptr amène l'une des copies à abandonner le pointeur. Lequel de ces restes dans le conteneur n'est pas défini. Par conséquent, vous pouvez perdre au hasard l'accès aux pointeurs si vous stockez auto_ptrs dans les conteneurs.

Les conteneurs STL doivent pouvoir copier les éléments que vous y stockez. Ils sont conçus pour que l'équivalent et l'original soient identiques. Les objets pointeur automatique ont un contrat complètement différent, dans lequel la copie crée un transfert de propriété. Cela signifie que les conteneurs de auto_ptr présenteront un comportement étrange, en fonction de l'utilisation.

Il existe une description détaillée de ce qui peut mal tourner dans le point 8 de Effective STL (Scott Meyers) et une description peu détaillée dans le point 13 de Effective C ++ (Scott Meyers).

Les conteneurs STL stockent des copies des éléments contenus. Lorsqu’un auto_ptr est copié, l’ancien ptr est défini sur null. De nombreuses méthodes de conteneur sont rompues par ce comportement.

La norme C ++ 03 (ISO-CEI 14882-2003) dit dans la clause 20.4.5, paragraphe 3:

  

[...]   [ Note: [...]   auto_ptr ne répond pas aux exigences CopyConstructible et Assignable pour la bibliothèque standard   éléments de conteneur et instancier ainsi un conteneur de bibliothèque standard   avec un auto_ptr entraîne un comportement indéfini. - note de fin ]

La norme C ++ 11 (ISO-CEI 14882-2011) dit dans l'annexe D.10.1, paragraphe 3:

  

[...]    Remarque: [...] les instances de auto_ptr répondent aux exigences de   MoveConstructible et MoveAssignable, mais ne répondent pas aux exigences   de CopyConstructible et CopyAssignable. - note de fin]

La

norme C ++ 14 (ISO-CEI 14882-2014) est expliquée à l'annexe C.4.2.  Annexe D: caractéristiques de compatibilité:

  

Modifier : les modèles de classe auto_ptr, unary_function et binary_function, les modèles de fonction random_shuffle et le   modèles de fonction (et leurs types de retour) ptr_fun, mem_fun,   mem_fun_ref, bind1st et bind2nd ne sont pas définis.
   Justification : remplacé par de nouvelles fonctionnalités.
   Effet sur la fonctionnalité d'origine : la compilation du code C ++ 2014 valide qui utilise ces modèles de classe et de fonction peut échouer   Norme internationale.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top