101 votes

C ++ renvoie un objet "NULL" si le résultat de la recherche est introuvable

Je suis assez novice en C++ donc j'ai tendance à concevoir avec beaucoup de Java-ismes alors que je suis en train d'apprendre. De toute façon, en Java, si j'avais une classe de "recherche" méthode qui retourne un objet T d'un Collection< T > correspondant à un paramètre spécifique, je voudrais renvoyer cet objet et si l'objet n'a pas été trouvé dans la collection, je retourne une valeur NULL. Puis, dans ma fonction d'appel, je voudrais juste vérifier if(T != NULL) { ... }

En C++, je suis la recherche que je ne peux pas retourner une valeur NULL si l'objet n'existe pas. Je veux juste de retour d'un "indicateur" de type T qui avise l'appelant de la fonction qu'aucun objet n'a été trouvé. Je ne veux pas lancer une exception, car il n'est pas vraiment une circonstance exceptionnelle.

class Node {
....

Attr& getAttribute(const string& attribute_name) const {
   //search collection
   //if found at i
        return attributes[i];
   //if not found
        return NULL;
}

private:
   vector<Attr> attributes;
}

76voto

Jesse Beder Points 14026

En C++, les références ne peuvent pas être null. Si vous souhaitez éventuellement retourner la valeur null si rien n'est trouvé, vous avez besoin de retourner un pointeur, pas une référence:

Attr *getAttribute(const string& attribute_name) const {
   //search collection
   //if found at i
        return &attributes[i];
   //if not found
        return NULL;
}

Sinon, si vous insistez sur le retour par référence, alors vous devez lever une exception si l'attribut n'est pas trouvé.

(En passant, je suis un peu inquiet à propos de votre méthode const et le retour d'un non-const d'attribut. Pour des raisons philosophiques, je vous suggère de revenir const Attr *. Si vous aussi, vous souhaiterez peut-être modifier cet attribut, vous pouvez surcharger avec une non-const méthode retournant un non-const d'attribut).

57voto

Kaz Dragon Points 3460

Il y a plusieurs réponses possibles ici. Vous souhaitez revenir à quelque chose qui pourrait exister. Voici quelques options, allant de moins ma préférée de préférée:

  • Retour par référence et le signal peut pas trouver par exception à la règle.

    Attr& getAttribute(const string& attribute_name) const 
    {
       //search collection
       //if found at i
            return attributes[i];
       //if not found
            throw no_such_attribute_error;
    }

Il est probable que de ne pas trouver d'attributs est une partie normale de l'exécution, et donc pas très exceptionnel. La gestion de ce serait bruyant. Une valeur null ne peut pas être renvoyé parce que c'est un comportement indéterminé d'avoir des références nulles.

  • Retour par pointeur

    Attr* getAttribute(const string& attribute_name) const 
    {
       //search collection
       //if found at i
            return &attributes[i];
       //if not found
            return NULL;
    }

Il est facile d'oublier de vérifier si un résultat de getAttribute serait un pointeur non NULL, et est une source facile de bugs.

  • Utiliser Boost.En option

    boost::optional<Attr&> getAttribute(const string& attribute_name) const 
    {
       //search collection
       //if found at i
            return attributes[i];
       //if not found
            return boost::optional<Attr&>();
    }

Un boost::optional signifie exactement ce qui se passe ici, et a des méthodes faciles pour vérifier si un tel attribut a été trouvé.

22voto

Mark Ransom Points 132545

Vous pouvez facilement créer un objet statique qui représente un retour NULL.

 class Attr;
extern Attr AttrNull;

class Node { 
.... 

Attr& getAttribute(const string& attribute_name) const { 
   //search collection 
   //if found at i 
        return attributes[i]; 
   //if not found 
        return AttrNull; 
} 

bool IsNull(const Attr& test) const {
    return &test == &AttrNull;
}

 private: 
   vector<Attr> attributes; 
};
 

Et quelque part dans un fichier source:

 static Attr AttrNull;
 

3voto

Brian R. Bondy Points 141769

Si vous voulez un NULL de la valeur de retour vous avez besoin d'utiliser des pointeurs au lieu de références.

Les références ne peuvent pas être eux-mêmes NULL.

(Note pour l'avenir de commentaires affiches: Oui, vous pouvez avoir l'adresse d'une référence NULL si vous avez vraiment vraiment essayer).

Voir ma réponse ici pour une liste des différences entre les références et les pointeurs.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X