Perché / quando usare (!! p) invece di (p! = NULL)
Domanda
Nel seguente codice, quali sono i vantaggi dell'utilizzo di (!! p)
anziché (p! = NULL)
?
AClass *p = getInstanceOfAClass();
if( !!p )
// do something
else
// do something without having valid pointer
Soluzione
È una questione di stile, in effetti sono equivalenti. Vedi questa domanda molto simile per la discussione.
Il confronto IMO con il puntatore null è più chiaro.
Altri suggerimenti
È praticamente lo stesso, anche se considero !! p
un cattivo stile e di solito indica che un programmatore sta cercando di essere intelligente.
Penso che il commento originale di GMan dovrebbe essere la risposta accettata:
Mi chiedo cosa c'è che non va nel solo
if (p)
Il punto è: niente è sbagliato e questo dovrebbe essere il modo preferito. Prima di tutto, !! p
è “troppo intelligente”; è anche del tutto superfluo e quindi negativo (nota: stiamo parlando di puntatori in un'istruzione if
qui, quindi il commento di Anacrolix, sebbene generalmente valido, non si applica qui!).
Lo stesso vale per p! = NULL
. Sebbene ciò sia possibile, non è necessario. È più codice, è completamente ridondante e quindi peggiora il codice. La cosa più vera che Jeff Atwood abbia mai detto è che "il miglior codice non è affatto un codice". Attenersi al minimo (che trasmette ancora il significato completo; se (p)
è completo).
Infine, if (p)
è probabilmente il modo più idiomatico di scrivere questo in C ++. Il C ++ si piega all'indietro per ottenere lo stesso comportamento per altri tipi di linguaggio (ad es. Flussi di dati), a scapito di alcune strane stranezze. La prossima versione dello standard introduce anche una nuova sintassi per raggiungere questo comportamento nei tipi definiti dall'utente.
Per i puntatori, otteniamo lo stesso gratuitamente. Quindi usalo.
/ EDIT: sulla chiarezza: sharptooth lo scrive
Il confronto IMO con il puntatore null è più chiaro.
Dichiaro che questo è oggettivamente sbagliato: se (p)
è più chiaro. Non è possibile che questa affermazione possa significare nient'altro, né in questo contesto né in nessun altro, in C ++.
Per quanto posso vedere, è solo un modo più breve per convertirlo in un valore booleano. Si applica! due volte, tuttavia, mentre p! = NULL
fa un confronto. Quindi immagino che il vantaggio sia solo un codice più breve, anche se più criptico se non sai cosa significhi !! p
.
Sono uguali, ma consiglio di usare
NULL != p
È più leggibile.
Non c'è differenza nell'esempio dato.
Tuttavia, l'ipotesi che ciò si applichi a tutti i casi non è corretta. a = not not b non è uguale a a = b , per quanto riguarda i tipi interi.
In C, 0
è falso. Tutto tranne 0
è vero. Ma non 0
è 1
e nient'altro. In C ++, true esegue il 1
come numero intero, non solo per la compatibilità all'indietro con C, ma perché 1
non è 0
e 1
è il valore più comune utilizzato per indicare true nei tipi bool C, compreso tipo bool C ufficiale e BOOL
usati in Win32.
Mentre per il codice di esempio fornito, !! p
non è necessario perché il risultato viene trasmesso a un bool
per la valutazione della condizione if
, ciò non esclude l'uso di !!
ai fini del cast di valori booleani ai valori interi previsti. Personalmente in questo esempio, per massimizzare la probabilità che i cambiamenti di tipo e la semantica siano chiari, userei NULL! = P
o p! = NULL
per chiarire cosa sia significava.
Questa tecnica è conosciuta come il linguaggio del doppio botto e questo ragazzo fornisce alcune buone giustificazioni .
NON !! NON usare la doppia negazione. Un semplice argomento è che dato che il C ++ è un sottoinsieme inglese limitato e l'inglese non ha una doppia negazione, allora chi parla inglese avrà molte difficoltà a analizzare ciò che sta succedendo.