2010-06-30 4 views
20

Le titre résume assez bien ma question. Pourquoi ne peut-on pas faire ce qui suit pour vérifier un pointeur nul?Pourquoi auto_ptr <T> l'opérateur!() Est-il défini?

auto_ptr<char> p(some_expression); 
// ... 
if (!p) // error 

Cela doit se faire à la place:

if (!p.get()) // OK 

Pourquoi ne pas auto_ptr<T> ont simplement operator!() défini?

+0

La question http://stackoverflow.com/q/2953530/427532 est quelque peu liée. –

Répondre

19

Semble être une erreur dans sa conception. Cela sera corrigé en C++ 0x. unique_ptr (remplacement pour auto_ptr) contient explicit operator bool() const;

Citation de nouvelle norme C++:

Le modèle de classe auto_ptr est dépréciée. [Note: Le modèle de classe unique_ptr (20.9.10) fournit une meilleure solution . Note -end]


Quelques précisions:
Q: Quel est le problème avec a.get() == 0?
A: Rien ne va pas avec a.get()==0, mais les pointeurs intelligents vous permettent de travailler avec eux car ils étaient de vrais pointeurs. operator bool() supplémentaire vous donne un tel choix. Je pense, que la vraie raison de faire auto_ptr déconseillé est qu'il n'a pas de conception intuitive. Mais operator bool pour unique_ptr dans la nouvelle norme signifie qu'il n'y a aucune raison de ne pas l'avoir.

+0

Question "stupide": que signifie "explicite" ici? Je l'ai seulement vu avec des constructeurs. –

+3

Cela signifie la même chose que cela signifie pour les constructeurs - que le constructeur ou l'opérateur de conversion ne participe pas à la conversion implicite qui se produit lorsque vous essayez de passer un objet à une fonction qui attend un argument de type différent –

+0

Sure, 'auto_ptr 'a été déprécié mais pourquoi est-ce que c'était une erreur de conception de ne pas avoir' operator!() '? Quel est le problème avec 'a.get() == 0'? –

8

En termes simples, il doit avoir operator !() défini. auto_ptr n'est pas un conteneur très bien conçu. Les pointeurs intelligents dans boost ont l'opérateur de conversion operator bool() défini qui peut être annulé avec operator !(). Cela permettra à votre if(!p) de compiler et de fonctionner comme prévu.

+9

"' auto_ptr' n'est pas un conteneur très bien conçu "résume-t-il assez bien. – Cogwheel

+3

'auto_ptr' n'est pas un conteneur. Aussi pourquoi devrait-il avoir 'operator!()' Défini? Si vous voulez le réclamer, je pense que vous devez justifier cette affirmation. Je ne vois aucune raison intrinsèque de le définir; Ce n'est pas comme si '(a.get() == 0)' n'est pas clair ou difficile à utiliser. –

+3

Si quelque chose est conçu pour agir comme un pointeur plus intelligent, alors ses interfaces devraient ressembler à un pointeur. – Cogwheel

0

Je suppose que car il était prévu que le passage à auto_ptr s à null serait un cas rare, pour éviter d'ajouter une interface supplémentaire, et de le rendre explicite lors de la vérification de null.

+0

Étant donné que auto_ptr :: operator = transfère la propriété et définit la source auto_ptr sur null, auto_ptr à null peut être assez commun. –

4

Il y a un problème avec la conversion booléenne. Il permet des syntaxes qui sont presque toujours une douleur. Heureusement, il existe une solution: l'expression Safe Bool.

Le problème avec une conversion à bool est que la conversion implicite est dangereuse. Par conséquent, operator bool() const est une abomination. Soit vous fournissez une méthode explicite ... soit vous utilisez l'idiome booléen sécurisé.

L'idée de l'idiome est de vous donner une instance d'un type avec un sous-ensemble assez minime d'opérations et presque aucun cas où la conversion implicite vous donnera des ennuis. Ceci est fait en utilisant un pointeur sur la fonction membre.

Des opérations telles que if (p) et if (!p) prennent tout leur sens, mais if (p < q) échouera à la compilation.

Lisez le lien à fond pour la solution complète, et vous comprendrez pourquoi c'était une bonne idée de ne pas avoir operator bool() const.

Questions connexes