2012-07-02 7 views
7

Dies kann eine dumme Frage, aber ich habe einen Code mit der folgenden Zeile:Seltsame C++ Syntax?

Solver *S, *STP = S = 
UseDummySolver ? createDummySolver() : new STPSolver(true); 

Ich kenne den ternären Operator, aber es ist das Gleichheitszeichen, die mir ein wenig verwirren. Kann mir jemand eine Erklärung geben? Vielen Dank.

+18

Das ist ein * sehr hässlich * bedeutet, zwei Variablen gleichzeitig zuzuweisen. * (brenne code [rs] so mit Feuer) * – user7116

+3

Es gibt viele Gründe, warum dieser Code einfach scheiße ist. Der doppelte Zuweisungsteil ist nur einer von ihnen. RAII nicht zu verwenden ist ein anderes. –

+0

Ja ... Ich wusste nicht einmal, dass das legal ist, und das habe ich noch nie gesehen! – steveha

Antwort

16

Schreibt, es ist

Solver *S; 
Solver *STP; 
S = UseDummySolver ? createDummySolver() : new STPSolver(true); 
STP = S; 

es aber sehr hässlich ist, würde ich nicht empfehlen, in Ihrem Code zu tun, dass.

Der empfohlene Weg wäre es zu schreiben, wie folgt (Verwendung der Initialisierung statt Zuweisung):

Solver *S = UseDummySolver ? createDummySolver() : new STPSolver(true); 
Solver *STP = S; 
+1

+1 Just beat me :) – NominSim

+2

Warum nicht Initialisierung, anstatt Zuweisung? – Nawaz

+0

@Nawaz Er erklärt gerade dem OP was der Code tatsächlich _does_ ist. – NominSim

2

Der ternäre Operator gibt einen Wert; Basierend auf dem booleschen Wert UseDummySolver gibt es entweder einen Dummy-Solver zurück oder gibt eine neue Instanz von STPSolver() zurück. Dieser Rückgabewert wird dann in STP und S gespeichert.

5

Sie sehen sich eine verkettete Aufgabe an.

Es ist das gleiche wie:

Solver *S; 
Solver *STP; 
S = UseDummySolver ? createDummySolver() : new STPSolver(true); 
STP = S; 
+0

@sixlettervariables Ja behoben, C++ nicht meine Stärke. – NominSim

+0

Timing ist alles :) +1 zu – houbysoft

+1

@sixlettervariables, NominSim, habe ich die Antwort bearbeitet und in die falsche Dereferenz eingefügt. Das tut mir leid; Der ursprüngliche Code hat mich verwirrt. Nicht die Schuld von NomininSim. – steveha

6

ich dieses empfehlen würde:

Solver *S = UseDummySolver ? createDummySolver() : new STPSolver(true); 
Solver *STP = S; 

Es prägnant, aber ordentlich und sauber.

Verwendet auch Initialisierung, anstatt Zuweisung. Sie sollten die Initialisierung über die Zuweisung bevorzugen, wo immer dies möglich ist.

+1

Gab Ihnen ein +1 für die Empfehlung für die Initialisierung vs Zuweisung :) – houbysoft

0

Ich würde es vorziehen, entweder diese:

std::unique_ptr<Solver> S ( UseDummySolver 
            ? createDummySolver() 
            : new STPSolver(true) ); 
Solver& STP = *S; 

oder dies:

std::shared_ptr<Solver> S ( UseDummySolver 
            ? createDummySolver() 
            : new STPSolver(true) ); 
std::shared_ptr<Solver> STP = S; 

Sowohl ein Problem mit dem Code vermeiden haben Sie da: wir nicht entscheiden müssen tun, was Zeiger auf Rufen Sie delete an, wenn die Objekte den Bereich verlassen (oder erinnern Sie sich an die Notwendigkeit, delete überhaupt aufzurufen). Stattdessen warten wir nur, bis die Variablen den Bereich verlassen, dann wird das Objekt Solver automatisch entfernt. STP ist im ersten Fall eindeutig nur eine andere Art des Zugriffs auf das Objekt, während es im Umfang ist, im zweiten Fall ist es ein unabhängiger "Miteigentümer" des Objekts und beide Zeiger können unabhängig voneinander neu zugewiesen werden.