2012-07-02 16 views
7

Questa può essere una domanda stupida ma ho un codice con la seguente riga:Strana sintassi C++?

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

so l'operatore ternario ma è l'uguale segni che mi confondono un po '. Qualcuno può darmi qualche spiegazione? Grazie.

+18

Questo è un * molto brutto * mezzo per assegnare due variabili contemporaneamente. * (masterizza codice [rs] come questo con il fuoco) * – user7116

+3

Ci sono molte ragioni per le quali questo codice fa schifo. La parte del doppio incarico è solo una di queste. Non usare RAII è un altro. –

+0

Sì ... non mi ero nemmeno reso conto che è legale, e non l'ho mai visto prima! – steveha

risposta

16

Scritto fuori, è

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

E 'molto brutto, però, io non consiglierei di farlo nel codice.

Il metodo consigliato sarebbe scrivere come segue (uso inizializzazione, anziché assegnazione):

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

+1 Picchiami :) – NominSim

+2

Perché non utilizzare l'inizializzazione, piuttosto che l'assegnazione? – Nawaz

+0

@Nawaz Sta solo spiegando all'OP ciò che effettivamente il codice _segue_. – NominSim

2

L'operatore ternario restituisce un valore; in base al valore booleano UseDummySolver, restituisce un risolutore fittizio o restituisce una nuova istanza di STPSolver(). Questo valore restituito viene quindi memorizzato in STP e S.

5

Stai guardando l'assegnazione concatenata.

E 'lo stesso di:

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

@sixlettervariables Sì, mi dispiace, C++ non è il mio forte. – NominSim

+0

Il tempismo è tutto :) +1 anche – houbysoft

+1

@sixlettervariables, NominSim, ho modificato la risposta e inserito il dereferenziamento errato. Mi dispiace per quello; il codice originale mi ha confuso. Non è colpa di NominSim. – steveha

6

Vorrei raccomandare questo:

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

è conciso, ma ordinato e pulito.

Inoltre, utilizza l'inizializzazione , anziché assegnazione. Dovresti preferire l'inizializzazione sull'assegnazione, laddove possibile.

+1

Ti ha dato un +1 per il suggerimento per l'inizializzazione vs assegnazione :) – houbysoft

0

io preferirei sia questo:

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

o questo:

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

Sia evitare un problema con il codice che hai lì: non abbiamo bisogno di fare decidere quale puntatore Chiama delete quando gli oggetti lasciano l'ambito (o, in effetti, ricorda la necessità di chiamare lo delete). Invece, aspettiamo solo che le variabili lascino l'ambito, quindi l'oggetto Solver viene rimosso automaticamente. STP è nel primo caso in modo univoco solo un altro modo di accedere all'oggetto mentre è nel campo di applicazione, nel secondo caso è un "comproprietario" indipendente dell'oggetto e entrambi i puntatori possono essere nuovamente assegnati in modo indipendente.