Ich bin ziemlich neu in C ++, daher neige ich dazu, während des Lernens mit vielen Java-Ismen zu entwerfen. Wenn ich in Java eine Klasse mit einer Suchmethode hätte, die ein Objekt T
von einem Collection< T >
zurückgibt, das einem bestimmten Parameter entspricht, würde ich dieses Objekt zurückgeben, und wenn das Objekt nicht in der Auflistung gefunden würde, würde ich zurückkehren null
. Dann würde ich in meiner aufrufenden Funktion einfach nachsehenif(tResult != null) { ... }
In C ++ stelle ich fest, dass ich keinen null
Wert zurückgeben kann, wenn das Objekt nicht vorhanden ist. Ich möchte nur einen 'Indikator' vom Typ T zurückgeben, der die aufrufende Funktion benachrichtigt, dass kein Objekt gefunden wurde. Ich möchte keine Ausnahme machen, weil es nicht wirklich ein außergewöhnlicher Umstand ist.
So sieht mein Code jetzt aus:
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;
}
Wie kann ich es ändern, damit ich diese Art von Marker geben kann?
quelle
std::find(first, last, value)
Gibt beispielsweise zurück,last
wenn kein Element übereinstimmt.Antworten:
In C ++ dürfen Referenzen nicht null sein. Wenn Sie optional null zurückgeben möchten, wenn nichts gefunden wird, müssen Sie einen Zeiger und keine Referenz zurückgeben:
Andernfalls sollten Sie eine Ausnahme auslösen, wenn Sie darauf bestehen, als Referenz zurückzukehren, wenn das Attribut nicht gefunden wird.
(Übrigens mache ich mir ein wenig Sorgen darüber, dass Ihre Methode
const
ein Nicht-const
Attribut ist und zurückgibt . Aus philosophischen Gründen würde ich die Rückgabe vorschlagenconst Attr *
. Wenn Sie dieses Attribut auch ändern möchten, können Sie es mit einer Nicht-const
Methode überladen Rückgabe eines Nicht-const
Attributs.)quelle
nullptr
stattNULL
für c ++ 11 zurückkehren?Hier gibt es mehrere mögliche Antworten. Sie möchten etwas zurückgeben, das möglicherweise vorhanden ist. Hier sind einige Optionen, die von meinen am wenigsten bevorzugten bis zu den am meisten bevorzugten reichen:
Rückgabe als Referenz und Signal kann ausnahmsweise nicht gefunden werden.
Es ist wahrscheinlich, dass das Nichtfinden von Attributen ein normaler Teil der Ausführung ist und daher nicht sehr außergewöhnlich. Die Handhabung hierfür wäre laut. Ein Nullwert kann nicht zurückgegeben werden, da es undefiniertes Verhalten ist, Nullreferenzen zu haben.
Rückkehr mit dem Zeiger
Es ist leicht zu vergessen, zu überprüfen, ob ein Ergebnis von getAttribute ein Nicht-NULL-Zeiger ist und eine einfache Fehlerquelle darstellt.
Verwenden Sie Boost.Optional
Ein boost :: optional zeigt genau an, was hier vor sich geht, und bietet einfache Methoden, um zu überprüfen, ob ein solches Attribut gefunden wurde.
Randnotiz: std :: optional wurde kürzlich in C ++ 17 gewählt, daher wird dies in naher Zukunft ein "Standard" sein.
quelle
boost::optional
erfordert nicht viel Overhead (keine dynamische Zuordnung), weshalb es so großartig ist. Die Verwendung mit polymorphen Werten erfordert das Umschließen von Referenzen oder Zeigern.Sie können problemlos ein statisches Objekt erstellen, das eine NULL-Rückgabe darstellt.
Und irgendwo in einer Quelldatei:
quelle
Wenn Sie einen
NULL
Rückgabewert wünschen , müssen Sie Zeiger anstelle von Referenzen verwenden.Referenzen können nicht selbst sein
NULL
.(Hinweis zu den zukünftigen Kommentarplakaten: Ja, Sie können die Adresse einer Referenz auf NULL setzen, wenn Sie es wirklich wirklich versuchen.)
In meiner Antwort hier finden Sie eine Liste der Unterschiede zwischen Referenzen und Zeigern .
quelle
Wie Sie herausgefunden haben, können Sie dies nicht so tun, wie Sie es in Java (oder C #) getan haben. Hier ist ein weiterer Vorschlag, Sie könnten die Referenz des Objekts als Argument übergeben und einen Bool-Wert zurückgeben. Wenn das Ergebnis in Ihrer Sammlung gefunden wird, können Sie es der übergebenen Referenz zuweisen und 'true' zurückgeben, andernfalls 'false'. Bitte beachten Sie diesen Code.
Die obige Funktion muss den Operator anhand des Schlüssels 'Token' finden. Wenn er den gefundenen findet, gibt er true zurück und weist den Wert dem Parameter Operator & op zu.
Der Aufrufercode für diese Routine sieht folgendermaßen aus
quelle
Der Grund, warum Sie hier nicht NULL zurückgeben können, ist, dass Sie Ihren Rückgabetyp als deklariert haben
Attr&
. Das Trailing&
macht den Rückgabewert zu einer "Referenz", die im Grunde genommen ein garantierter Nullzeiger auf ein vorhandenes Objekt ist. Wenn Sie null zurückgeben möchten, wechseln SieAttr&
zuAttr*
.quelle
Sie können nicht zurückkehren,
NULL
da der Rückgabetyp der Funktion ein Objektreference
und kein a istpointer
.quelle
Sie können dies versuchen:
quelle