Frage

Ich bin ziemlich neu in C ++, damit ich mit vielen Java-isms zu entwerfen neige, während ich lernen werde. Wie auch immer, in Java, wenn ich Klasse mit einer ‚Suche‘ Methode habe, die ein Objekt T von einem Collection< T > zurückkehren würde, dass ein bestimmten Parameter angepasst, würde ich das Objekt zurückgeben und wenn das Objekt nicht in der Sammlung gefunden wurde, würde ich null zurückkehren . Dann in meiner Berufung Funktion würde ich nur überprüfen if(tResult != null) { ... }

In C ++, ich finde, dass ich keinen null Wert zurückgeben kann, wenn das Objekt nicht existiert. Ich will nur eine ‚Anzeige‘ vom Typ T zurück, dass die anrufende Funktion meldet, dass kein Objekt gefunden wurde. Ich will nicht eine Ausnahme werfen, weil es nicht wirklich ein außergewöhnlicher Umstand ist.

Dies ist, was mein Code sieht jetzt:

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?

War es hilfreich?

Lösung

In C ++ Referenzen können nicht null sein. Wenn Sie null optional zurückkehren wollen, wenn nichts gefunden wird, müssen Sie einen Zeiger zurück, keine Referenz:

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

Andernfalls, wenn Sie bei der Rückkehr durch Verweis darauf bestehen, dann sollten Sie eine Ausnahme auslösen, wenn das Attribut nicht gefunden wird.

(By the way, ich bin ein wenig besorgt über Ihre Methode const ist und eine nicht-const Attribut zurück. Für philosophischen Gründen, würde ich vorschlagen, const Attr * zurückkehren. Wenn Sie auch dieses Attribut ändern möchten, können Sie Überlast mit einem Verfahren, nicht-const ein nicht const Attributs als auch.)

Rückkehr

Andere Tipps

Es gibt mehrere mögliche Antworten hier. Sie wollen etwas zurückgeben, die existieren könnte. Hier sind einige Möglichkeiten, die von mir am wenigsten bevorzugt am meisten bevorzugt:

  • Zurück Bezug genommen wird, und Signal-nicht-finden von Ausnahme.

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

Es ist wahrscheinlich, dass nicht Attribute findet ein normaler Bestandteil 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, weil es nicht definiertes Verhalten ist null Referenzen zu haben.

  • Zurück von Zeigern

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

Es ist einfach zu überprüfen, um zu vergessen, ob ein Ergebnis von getAttribute ein Nicht-NULL-Zeiger sein würde, und ist eine einfache Fehlerquelle.

  • Verwenden Sie Boost.Optional

    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&>();
    }

A boost :: optional bedeutet genau das, was hier los ist, und hat einfache Methoden zum Prüfen, ob ein solches Attribut gefunden wurde.


Randbemerkung:. Std :: optional wurde vor kurzem in C ++ stimmte 17, so dass dies ein "Standard", was in naher Zukunft sein wird,

Sie können ganz einfach ein statisches Objekt erstellen, die eine NULL Rückkehr darstellt.

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; 
};

Und irgendwo in einer Quelldatei:

static Attr AttrNull;

Wenn Sie einen NULL Rückgabewert wollen, müssen Sie Zeiger anstelle von Referenzen verwenden.

Referenzen können sich nicht NULL sein.

. (Hinweis auf den zukünftigen Kommentar Poster: Ja, Sie die Adresse einer Referenz haben können NULL sein, wenn Sie wirklich, wirklich versuchen)

Siehe meine Antwort hier für die Liste Unterschiede zwischen den Referenzen und Zeigern .

Wie Sie herausgefunden haben, dass Sie es nicht tun, wie Sie in Java (oder C #) getan haben. Hier ist ein weiterer Vorschlag, könnten Sie in der Referenz des Objekts als Argument und Rückkehr Bool Wert übergeben. Wenn das Ergebnis in Ihrer Sammlung zu finden ist, können Sie es mit der Referenz vergeben wird weitergegeben und Rückkehr ‚true‘, andernfalls Rückkehr ‚false‘. Bitte beachten Sie diesen Code.

typedef std::map<string, Operator> OPERATORS_MAP;

bool OperatorList::tryGetOperator(string token, Operator& op)
{
    bool val = false;

    OPERATORS_MAP::iterator it = m_operators.find(token);
    if (it != m_operators.end())
    {
        op = it->second;
        val = true;
    }
    return val;
}

Die Funktion oben hat den Betreiber gegen den Schlüssel ‚token‘ finden, wenn es die findet man es wahr zurückgibt und den Wert auf Parameter Operator & op zuweisen.

Der Anrufer-Code für diese Routine wie folgt aussieht

Operator opr;
if (OperatorList::tryGetOperator(strOperator, opr))
{
    //Do something here if true is returned.
}

Der Grund, dass Sie nicht NULL zurückgeben können hier ist, weil Sie Ihren Rückgabetyp als Attr& deklariert haben. Der Hinter & macht den Rückgabewert eine „Referenz“, die im Grunde ist ein garantierte-not-to-be-Null-Zeiger auf ein vorhandenes Objekt. Wenn Sie möchten in der Lage sein null zurückzukehren, ändern Attr& zu Attr*.

Sie sind nicht in der Lage NULL zurückkehren, weil der Rückgabetyp der Funktion ein Objekt reference ist und kein pointer.

Sie können versuchen, diese:

return &Type();
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top