2013-02-14 7 views
31

Ich bin sehr neu in C++ und hier ist meine Situation. Ich habe einen Verweis auf MyOjbect, aber das genaue Objekt hängt von einer Bedingung ab. Deshalb möchte ich, so etwas tun:Wie man eine Referenz deklariert und später initialisiert

MyObject& ref; 
if([condition]) 
    ref = MyObject([something]) 
else 
    ref = MyObject([something else]); 

ich nicht dieses Recht jetzt tun kann, weil der Compiler mir nicht erlauben zu erklären, aber keinen Verweis initialisieren. Was kann ich tun, um mein Ziel hier zu erreichen?

+2

Wäre das eine Initialisierung von einem temporären? Das funktioniert auch ohne die Bedingung: 'MyObject & ref = MyObject ([something]);', weil Sie eine temporäre nicht an eine nicht-konstante lvalue-Referenz binden können. – GManNickG

+0

@GManNickG: gilt das auch für Zaffy und suszterpatt Antworten? – qPCR4vir

+0

@ qPCR4vir: Ja. Die Frage steht in gewisser Weise immer noch nicht direkt. – GManNickG

Antwort

30

Sie müssen es initialisieren. Aber wenn Sie es bedingt initialisieren möchten, können Sie Folgendes tun:

MyObject& ref = (condition) ? MyObject([something]) : MyObject([something else]); 
+2

Ich kann das nicht tun, weil ich tatsächlich Sachen innerhalb dieser Bedingungen mache. Ich bin hier sehr verwirrt. Das sieht für mich wie ein ziemlich häufiges Szenario aus, warum ist das nicht erlaubt? Ist mein Codierungsstil das Anti-C++? – user1861088

+3

@ user1861088: "Ich kann das nicht tun, weil ich unter diesen Bedingungen tatsächlich Sachen mache" Warum zeigst du nicht eigentlich, was du in der Frage zu tun versuchst? – GManNickG

+0

was ich sagen wollte ist, dass ich mehrere Codezeilen innerhalb jeder Bedingung ausführe, anstatt nur eine Funktion aufzurufen, die einen Wert zurückgibt. Also kann ich nicht verwenden? : Recht? – user1861088

9

In C++ können Sie keine Referenz ohne Initialisierung deklarieren. Sie müssen es initialisieren.

+1

Ich verstehe das. Also irgendwelche Tipps zu einem Rundgang? Grundsätzlich brauche ich die Referenz in einem größeren Umfang als die Bedingung. – user1861088

+0

@ user1861088 In diesem Fall, entweder 1. Redesign Ihren Code (bevorzugt), 2. Verwenden Sie einen Zeiger (nicht bevorzugt). –

+1

3. Verwenden Sie keine Referenz, verwenden Sie einfach ein Objekt –

8

Kurze Antwort: Sie nicht.

Geringfügig längere Antwort: etwas tun, wie folgt aus:

MyObject& getObject() 
{ 
    if([condition]) 
     return [something] 
    else 
     return [something else]; 
} 

MyObject& ref = getObject(); 

Übliche Haftungsausschlüsse in Bezug auf Referenzen gelten selbstverständlich.

+0

Ja, ich dachte daran, aber .. es ist einfach komisch, dass ich all dies tun muss, um ein scheinbar einfaches Ziel zu erreichen :( – user1861088

+0

Warum gibt 'getObject() 'eine Referenz zurück? Worauf bezieht es sich? –

+0

& Jonathan: That fällt unter die "üblichen Disclaimers" Bit.;) – suszterpatt

10

Sie können dies nicht tun. Referenzen müssen an etwas gebunden sein, mag Ihnen nicht gefallen, aber es verhindert eine ganze Klasse von Fehlern, denn wenn Sie eine Referenz haben, können Sie immer annehmen, dass sie an etwas gebunden ist, im Gegensatz zu einem Zeiger, der null sein könnte.

Ihr Beispielcode würde sowieso nicht funktionieren, weil Sie versuchen, eine nicht konstante Referenz an ein temporäres Objekt zu binden, das ungültig ist.

Warum brauchen Sie es als Referenz? Eine Lösung wäre, Ihre Art zu gewährleisten, hat ein kostengünstiges Standard-Konstruktor und effizient bewegt wird, dann nur tun:

MyObject obj; 
if([condition]) 
    obj = MyObject([something]) 
else 
    obj = MyObject([something else]); 

Andernfalls würden Sie den bedingten Code in einer oder mehr Funktionen setzen müssen, entweder:

const MyObject& ref = createObject([condition]); 

oder

const MyObject& ref = [condition] ? doSomething() : doSomethingElse(); 

Hinweis, dass diese beiden Versionen verwenden eine const Referenz, die zu einer temporären binden kann, wenn das Objekt muss nicht const sein, dann wieder aufhören zu versuchen, einen Verweis zu verwenden:

MyObject obj = createObject([condition]); 

Dies wird wahrscheinlich genauso effizient sein wie das, was Sie zu tun versuchen, dank die return value optimization

9

AFAIK kann dies‘ t mit einer Referenz getan werden. Sie müssen einen Zeiger verwenden:

MyClass *ptr; 

if (condition) 
    ptr = &object; 
else 
    ptr = &other_object; 

Der Zeiger wird ähnlich wie eine Referenz handeln. Vergessen Sie nicht, -> für den Mitgliederzugriff zu verwenden.

+1

Sie können eine Referenz einfach als 'MyClass & ref = * ptr' deklarieren, wenn Sie sie in eine Referenz umwandeln wollen ... – poizan42

+0

Deklaration als Zeiger löscht nicht den Fall, dass rvalue die Rückgabe einer Funktion ist –

3
MyClass *ptr; 

if (condition) 
    ptr = &object; 
else 
    ptr = &other_object; 

MyClass &ref = *ptr; 
+2

Bei der Beantwortung , überlege dir, eine Erklärung für den Code zu schreiben, den du geschrieben hast, und diese Antwort fügt der * sehr * alten Frage absolut nichts Neues hinzu. – Ajean

+1

Das sieht dem Code von [dieser Antwort] sehr ähnlich (http://stackoverflow.com/a/14885051). –

+0

Während der Mangel für jede Erklärung schlecht ist, ist dies immer noch die einzige wirkliche Antwort, die nichts Zusätzliches einführt oder Sie auf das begrenzt, was in einem ternären Operator geschrieben werden kann ... – poizan42

0

Sie können "extern" Schlüsselwort verwenden: zum ersten Mal (unter der Annahme, in Header-Datei) können Sie Ihre Variable vorhergehende Erklärung mit "extern" Schlüsselwort deklarieren. Später (in der Quelldatei) wiederholen Sie die Deklaration ohne "extern" und weisen ihr einen Wert zu.

Verwandte Themen