Ich bin es gewohnt, in meinen C ++ - Anwendungen so eine Zeichenfolge zu übergeben:
%Vor%Jetzt habe ich einen Fall, in dem die Zeichenfolge NULL sein soll:
%Vor% Ich könnte foo
ändern in:
Aber um ein String-Literal zu übergeben oder ein char*
auf diese Implementierung von foo
zu kopieren, muss ich etwas schreiben:
Ich habe angefangen, darüber nachzudenken, von std::string
zu erben und eine null
-Eigenschaft hinzuzufügen, aber ich bin mir nicht sicher, ob das eine gute Idee ist. Vielleicht ist es besser, einfach eine const char*
-Zeichenfolge für Parameter zu verwenden, die NULL sein können, aber was ist, wenn ich eine Kopie der Zeichenfolge (oder NULL) speichern möchte, ohne selbst den Speicher verwalten zu müssen? (Siehe Was sind einige der Nachteile zu verwenden C-Style Strings? usw.)
Irgendeine clevere Lösung?
Wenn Sie möchten, dass der Typ null ist, dann machen Sie einen Zeiger. Übergeben Sie String-Zeiger anstelle von Referenzen, da dies genau das ist, was Zeiger tun können, und Referenzen können nicht. Referenzen zeigen immer auf dasselbe gültige Objekt. Zeiger können auf null gesetzt werden oder auf ein anderes Objekt verweisen. Wenn Sie also die Dinge brauchen, die Zeiger tun können, verwenden Sie Zeiger.
Alternativ können Sie boost :: optional verwenden, was eine typsicherere Methode zur Angabe von "diese Variable enthält möglicherweise einen Wert" enthält.
Oder ändern Sie die Semantik natürlich so, dass Sie entweder leere Strings anstelle von null verwenden, einen separaten bool -Parameter übergeben, der angibt, ob der String verfügbar ist oder nicht, oder refactor, so dass Sie ihn nicht benötigen.
Funktion überladen zur Rettung ...
%Vor%Dies akzeptiert sowohl c-artige char-Arrays als auch std :: strings und verursacht zusätzlichen Overhead auf dem Stack, wenn Sie ein String-Literal oder ein char-Array übergeben, aber Sie können Ihre Implementierung an einer Stelle halten und behalten Deine nette Syntax.
Persönlich würde ich die Semantik ändern, um leere std :: strings anstelle von NULL zu übergeben:
%Vor%Oder mischen Sie ein bisschen zwei vorherige Antworten:
%Vor%Gleiche Schnittstelle, keine Kopie auf dem Stapel. Sie könnten, wenn Sie möchten, auch fooImpl inline.
Warum überlädst du die Funktion nicht und gibst der zweiten Überladung kein Argument? Dann können beide Überladungen intern eine Funktion aufrufen, die die Leselogik bereitstellt und die selbst einen Zeiger an std::string
übergibt.
Was ist, wenn Sie nur Folgendes verwenden:
%Vor% Ja, dies führt zu einer zusätzlichen Zuweisung und Kopie, und der Aufruf der Funktion ist etwas ausführlicher, weil Sie im üblichen Fall .c_str()
verwenden müssen, aber es gibt Ihnen die gewünschte Semantik.