Wie kann man vermeiden explizit einen Konstruktor aufrufen, wenn sie durch Bezugnahme in C ++ temporäre Objekt übergeben?

StackOverflow https://stackoverflow.com/questions/1008272

  •  06-07-2019
  •  | 
  •  

Frage

Lassen Sie uns sagen, ich habe eine Klasse:

class String
{
public:
     String(char *str);
};

Und zwei Funktionen:

void DoSomethingByVal(String Str);
void DoSomethingByRef(String &Str);

Wenn ich rufe DoSomethingByVal wie folgt aus:

DoSomethingByVal("My string");

Der Compiler findet heraus, dass es ein temporäres String-Objekt erstellen sollte und rufen Sie die char * Konstruktor.

Allerdings, wenn ich versuche, DoSomethingByRef die gleiche Art und Weise zu verwenden, erhalte ich eine „Kann konvertieren Parameter nicht von‚char *‘auf‚String &‘“ Fehler.

Stattdessen muss ich explizit eine Instanz erstellen:

DoSomethingByRef(String("My string"));

das kann preety ärgerlich.

Gibt es eine Möglichkeit, dies zu vermeiden?

War es hilfreich?

Lösung

Sie müssen durch konstante Referenz weitergeben müssen:

Für:

void DoSomethingByVal(String Str);

In dieser Situation wird der Compiler zunächst eine temporäre Variable erstellt. Dann wird die temporäre Variable in die Parameter aufgebaut kopieren.

Für:

void DoSomethingByRef(String const& Str);

In dieser Situation wird der Compiler eine temporäre Variable erstellt. Aber temporäre Variablen können nicht auf eine Referenz gebunden werden können sie nur auf eine konstante Referenz gebunden werden, um Ihre ursprüngliche Funktion nicht aufgerufen werden kann. Beachten Sie die std :: string Objekte Konstruktor nimmt eine konstante Referenz der Parameter des Kopierkonstruktors ist und deshalb die erste Version arbeitet als die temporäre nur auf die konstante Referenz Parameter des Copykonstruktor gebunden ist.

Andere Tipps

Hmm, ich bin nicht sicher, ob

void DoSomethingByRef(String &Str);
DoSomethingByRef(String("My string"));

würde tatsächlich kompilieren. Ein R-Wert kann nicht auf nicht-const zu einer Referenz binden (weil ein ref nicht-const wird unter Angabe werden Sie den Wert ändern, und es wäre nicht sinnvoll, ein vorübergehenden zu ändern). Sind Sie sicher, dass Sie nicht tun:

String str("My string");
DoSomethingByRef(str);

Wenn Sie DoSomethingByVal wollen einen R-Wert nehmen, der Parameter hat ein Verweis auf const sein:

void DoSomethingByRef(const String &Str);

Fabrikat:

DoSomethingByRef (const String & str);

"My String" ist kein String, ist es ein c-string, ein char *, wenn man so will. Sie müssen, dass c-String in ein String-Objekt setzen, und dann können Sie das neue String-Objekt als Verweis übergeben.

Ein weiterer Punkt, Sie vorbei bereits ein char * ... das ist ziemlich leicht, nur ein Zeiger. Warum sorgen sich um ein neues Objekt durch Bezugnahme vorbei? zuteilen gerade ein neues Objekt in diesem Konstruktor aus dem Heap und kopieren Sie die c-string hinein.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top