Je suis assez nouveau en C ++, donc j'ai tendance à concevoir avec beaucoup de Java-isms pendant que j'apprends. Quoi qu'il en soit, en Java, si j'avais une classe avec une méthode de recherche qui renverrait un objet à T
partir d'un Collection< T >
qui correspond à un paramètre spécifique, je retournerais cet objet et si l'objet n'était pas trouvé dans la collection, je le retournerais null
. Ensuite, dans ma fonction d'appel, je vérifierais simplementif(tResult != null) { ... }
En C ++, je découvre que je ne peux pas renvoyer une null
valeur si l'objet n'existe pas. Je veux juste renvoyer un «indicateur» de type T qui notifie à la fonction appelante qu'aucun objet n'a été trouvé. Je ne veux pas lancer d'exception car ce n'est pas vraiment une circonstance exceptionnelle.
Voici à quoi ressemble mon code en ce moment:
class Node {
Attr& getAttribute(const string& attribute_name) const {
//search collection
//if found at i
return attributes[i];
//if not found
return NULL; // what should this be?
}
private:
vector<Attr> attributes;
}
Comment puis-je le changer pour pouvoir donner ce type de marqueur?
la source
std::find(first, last, value)
renvoielast
si aucun élément ne correspond.Réponses:
En C ++, les références ne peuvent pas être nulles. Si vous souhaitez éventuellement retourner null si rien n'est trouvé, vous devez renvoyer un pointeur, pas une référence:
Sinon, si vous insistez pour renvoyer par référence, vous devez lancer une exception si l'attribut n'est pas trouvé.
(Au fait, je suis un peu inquiet du fait que votre méthode soit
const
et renvoie un non-const
attribut. Pour des raisons philosophiques, je vous suggère de revenirconst Attr *
. Si vous souhaitez également modifier cet attribut, vous pouvez surcharger avec une non-const
méthode renvoyant également un non-const
attribut.)la source
nullptr
au lieu deNULL
pour c ++ 11 maintenant?Il y a plusieurs réponses possibles ici. Vous souhaitez renvoyer quelque chose qui pourrait exister. Voici quelques options, allant de la moins préférée à la plus préférée:
Retour par référence et signal introuvable par exception.
Il est probable que ne pas trouver d'attributs soit une partie normale de l'exécution, et donc pas très exceptionnelle. La manipulation pour cela serait bruyante. Une valeur nulle ne peut pas être retournée car il est un comportement non défini d'avoir des références nulles.
Retour par pointeur
Il est facile d'oublier de vérifier si un résultat de getAttribute serait un pointeur non NULL et constitue une source facile de bogues.
Utilisez Boost.
Un boost :: optional signifie exactement ce qui se passe ici, et a des méthodes simples pour inspecter si un tel attribut a été trouvé.
Note latérale: std :: optional a été récemment voté en C ++ 17, donc ce sera une chose "standard" dans un proche avenir.
la source
boost::optional
n'implique pas beaucoup de frais généraux (pas d'allocation dynamique), c'est pourquoi c'est si génial. Son utilisation avec des valeurs polymorphes nécessite des références d'encapsulation ou des pointeurs.Vous pouvez facilement créer un objet statique qui représente un retour NULL.
Et quelque part dans un fichier source:
la source
Si vous voulez une
NULL
valeur de retour, vous devez utiliser des pointeurs au lieu de références.Les références ne peuvent pas être elles-mêmes
NULL
.(Remarque pour les futurs commentaires des affiches: Oui, vous pouvez avoir l'adresse d'une référence NULL si vous essayez vraiment de le faire).
Voir ma réponse ici pour une liste des différences entre les références et les pointeurs .
la source
Comme vous l'avez compris, vous ne pouvez pas le faire comme vous l'avez fait en Java (ou C #). Voici une autre suggestion, vous pouvez passer la référence de l'objet comme argument et renvoyer une valeur booléenne. Si le résultat se trouve dans votre collection, vous pouvez l'affecter à la référence passée et renvoyer «true», sinon renvoyer «false». Veuillez considérer ce code.
La fonction ci-dessus doit trouver l'opérateur par rapport à la clé 'token', si elle trouve celle qu'elle renvoie true et affecter la valeur au paramètre Operator & op.
Le code de l'appelant pour cette routine ressemble à ceci
la source
La raison pour laquelle vous ne pouvez pas renvoyer NULL ici est que vous avez déclaré votre type de retour comme
Attr&
. La fin&
fait de la valeur de retour une "référence", qui est fondamentalement un pointeur garanti non nul vers un objet existant. Si vous souhaitez pouvoir renvoyer null, passezAttr&
àAttr*
.la source
Vous ne pouvez pas retourner
NULL
car le type de retour de la fonction est un objetreference
et non unpointer
.la source
Vous pouvez essayer ceci:
la source