Wie NULL zurück, von einer Methode in eine Vorlage-Klasse
Habe ich eine Methode die wie folgt aussieht:
template <typename T>
T Test<T>::FindItem(T item)
{
if(found)
//return original value, no problem here
else
//I want to return NULL here, like:
return NULL;
}
Dieser schlägt fehl, in bestimmten Fällen zur Laufzeit, weil einige die Werte nicht umgewandelt werden kann, um die NULL in C++ z.B. std::string
. Welchen Ansatz sollte ich verfolgen hier?
- Seine eine compile-Zeit-Fehler. Kein run-time.
- Laufzeit für std::string, std::string(const char*) aufgerufen werden
- Ich benutze Visual Studio 2005 und VC-compiler und es ist nicht eine compile-Zeit-Fehler in der it. Kann nicht sagen, über gcc.
- Oops..sorry, mein Fehler. Ja es stürzt in VS2008 auch.
- Initialisieren eines
std::string
mitNULL
ist nicht eine compile-Zeit-Fehler, aber ruft nicht definiertes Verhalten, wahrscheinlich in Ermangelung an Zeit ausführen.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Wenn Sie zurückkehren möchten, von Wert und don ' T wollen, um Durcheinander mit der Rückkehr Zeiger und new/delete ist, können Sie nur tun, wie diese:
und verwenden Sie es auf diese Weise:
Hier, Stroustrup gibt ein paar Argumente, die für die Vermeidung von
NULL
in C++:0
, so gibt es keinen tatsächlichen Gewinn [mehr zu geben]Den Vorschlag, wieder von der Seite:
0
oder (für C++0xwhatever)nullptr
.Zweitens, wenn Sie zurückkehren möchten, ein Ungültiger Zeiger als ein signal des Scheiterns, müssen Sie deklarieren Sie die Funktion als Rückgabe einen Zeiger auf einen Typ, nicht der Typ selbst.
Dritten, die meisten standard-Bibliothek finden () - Funktionen Iteratoren zurückgeben, anstatt die Elemente direkt. Das gibt Ihnen die Möglichkeit zu implementieren, die "nichts gefunden" Fall anders.
null
Schlüsselwort ist ein Versagen der design-Sprache, trotz aller Argumente Stroustrup gegeben hat. Zeiger sind anders als die zahlen, Zeit, und so sollten Sie syntaktisch Verschieden.Haben Sie eine Funktion, zurückgeben könnte ein gültiges Objekt, aber auch ein Indiz dafür, dass kein gültiges Objekt vorhanden ist. Kombiniert mit einer situation, wo alle möglichen Objekt-Werte gültig sind, ist dies ein design-problem mit der find-Funktion. (Auch wenn Sie optimiert die Funktion so, dass wäre es beispielsweise, eine leere Zeichenfolge zurück, wenn es keines findet, wie wäre dies zu unterscheiden von erfolgreichen Suche nach einem leeren string?)
Laufe der Zeit mehrere Wege aus diesem dilemma gefunden wurden. So könnte man zurück einen Zeiger/iterator zurückgegeben wird, sondern der tatsächliche Wert. Dann ein
NULL
Zeiger/Ende-iterator geben würde, "nicht gefunden". Oder man könnte einen Wert von nicht-const-Referenz, weisen Sie das Ergebnis und zeigen den Erfolg/Misserfolg durch ein boolean zurückgegeben. Oder nehmen Sie eine der anderen Lösungen hier gepostet. Aber alle verlangen, dass Sie ändern Sie die Funktion der Schnittstelle -- weil, wie es ist, hat es ein design-Fehler.Sowieso, vor dem Sprung in und tun dies, sollten Sie sich Fragen, warum Sie schreiben Ihre eigenen container/Algorithmus anstelle der Verwendung eines aus der std-lib.
Meisten Arten sind in Standard-constructable haben Sie eine Eigenschaften-template-Klasse kann spezialisiert werden (mit der Standard-Rückgabe eines default-initialisiert Objekt).
Sollten Sie wieder T* nicht-T
Da bin ich jetzt vielleicht zu simpel, aber ich bevorzuge einfach die Rücksendung eines
bool
:item
pro Exemplar.Meiner Meinung nach versucht Ihr, erschweren Sie sich ein wenig, indem Sie versuchen, einen NULL-Wert zurück...
Stattdessen etwas tun, ähnlich wie diese:
Werfen eine leere Klasse kostet nichts...
Sie könnte eine exception werfen, wenn es nicht gefunden wird.
Da Sie keine Kenntnis von der Art sah-und zurückgegeben, Sie können nicht benennen, irgendeinen bestimmten Wert von diesem Typ als ein Fehler-code. Im wesentlichen werden Sie versuchen, drücken Sie die vollständige domain von einem Typ plus ein Fehler-Wert in der Domäne des Typ.
Vorschläge zu verwenden, Iteratoren oder anderen Verpackungen helfen, das problem zu lösen durch die Erweiterung der Domäne der return-Typ, umfassen die Fehler-Werte, aber wenn Sie wollen, zu bleiben, um die tatsächlichen Typen Sie es zu tun haben, Ausnahmen sind Sie am besten andere Wahl. Das ist, was Sie sind für.
Zurück
T()
. WennT
ist der Typsometype *
es wird initialisiert werden, um einen null-Zeiger. WennT
ist der Typsometype
, wird es wieder ein Objekt erstellt mit den default-Konstruktor, das sollte reichen (std::string
leer, Integrale Typen wieint
s 0, etc).atoi()
hat das gleiche problem.