2013-05-10 9 views
20

Devo essere in grado di distinguere tra NULL e 0 in C++.C++ triple equals?

C'è un modo per utilizzare qualcosa come l'operatore === per indicare la differenza tra NULL e 0 in C++?

+7

Puoi dare un esempio di come potresti eseguire questo confronto in primo luogo? 'int *' e 'int' sono due cose completamente differenti. Dovresti eseguire il cast per poterli confrontare, il che significa che ti stai impegnando a rendere ambiguo questo confronto. – tadman

+5

C++ non funziona così. Sembra che tu stia abusando completamente dei puntatori. – SLaks

+26

Usa 'nullptr' invece di' NULL', problema risolto. – Blastfurnace

risposta

30

NULL è una macro del preprocessore e verrà sostituita direttamente con 0 quando viene eseguito il preprocessore. Quindi, in breve, no.

+7

Esiste un operatore '===', in Javascript. Sta chiedendo quale sia l'equivalente in C++. –

+0

@BenVoigt Ah capisco. – RandyGaul

15

Non v'è alcuna differenza - NULL è necessario essere definito come un costante intera con il valore 0. Il tipo intero viene in genere scelto per avere le stesse dimensioni di un puntatore, ma non è effettivamente necessario. In C è spesso definito come (void *)0, ma questo è non consentito in C++ (in C è ragionevole perché un puntatore a void supporta la conversione implicita a qualsiasi altro tipo di puntatore - ma in C++ non è consentito, quindi se NULL sono stati definiti come un puntatore a vuoto, dovresti lanciarlo per ottenere qualsiasi altro tipo di puntatore).

Quando/se si vuole un puntatore nulloche è distinguibile dalla 0, probabilmente desidera utilizzare nullptr. nullptr può essere assegnato ad una variabile di qualsiasi tipo puntatore, ma può non essere assegnata a un tipo intero (ad esempio, int, long, size_t, ecc)

+1

Non è 'NULL' definito come approssimativamente' (void *) 0'? – tadman

+2

@tadman: In C è, in C++ no. C++ NULL è o '0' o' 0u' o '0uL' o' 0uLL' - in particolare è necessario avere un tipo integrale. –

+0

Grazie per aver chiarito. – tadman

30

Tale operatore non è necessaria in C++, perché c'è nessun tipo built-in che sia in grado di memorizzare entrambi questi valori in modo significativamente distinguibile. Inoltre, NULL non è richiesto in C++, perché è possibile sostituirlo con lo zero 0 ovunque sia disponibile uno NULL. Bjarne Stroustrup anche suggerisce di evitare del tutto NULL:

In C++, la definizione di NULL è 0, per cui v'è solo una differenza estetica. Preferisco evitare i macro, quindi uso 0. Un altro problema con NULL è che le persone allo a volte credono erroneamente che sia diverso da 0 e/o non un intero. Nel codice pre-standard, NULL era/è talvolta definito come qualcosa di non adatto e pertanto doveva/doveva essere evitato. Questo è meno comune in questi giorni.

+2

+1 Questo è il nocciolo del problema. In C++ rispondi a questa domanda con un typecheck. –

+0

Bene, ci sono molti tipi che possono memorizzare sia 'NULL' che' 0': tutti i tipi interi. 'NULL' semplicemente ** è **' 0'. Ovviamente non esiste un tipo che possa memorizzare sia 0 sia un puntatore nullo, ma questa è una storia diversa. – Angew

+0

@Angew Questo sarebbe lo stesso valore, però. In altre lingue, come Javascript, dove '===' ha origine, zero è un oggetto e NULL non lo è. In C++ sia NULL che zero sono indistinguibili. – dasblinkenlight

1

In generale NULL e 0 sono la stessa cosa in C++ (entrambi sono un puntatore nullo).

ho intenzione di assumere si sta chiedendo come ottenere un tipo integrale in C++ che può avere sia NULL e 0 valori, e per essere in grado di capire la differenza.

Si può fare questo con boost::optional:

boost::optional<int> val; 

if(!val) 
    std::cout << "null" << std::endl; 
else 
    std::cout << "val=" << *val << std::endl; 

val = 0; 
if(!val) 
    std::cout << "null" << std::endl; 
else 
    std::cout << "val=" << *val << std::endl; 

Questo dovrebbe stampare null e val=0.

10

Penso che quello che stai chiedendo è:

Se ho una variabile x, come posso distinguere tra

  1. x contiene una numerico 0
  2. x manca/no valore/null pointer

Il C++ ha variabili fortemente tipizzate, quindi è inusuale persino avere una variabile in cui entrambe sono possibilità. Ma la logica con valori NULL è utile nei database, quindi vediamo alcuni modi per rappresentarli in C++.

  1. Situazione: x == 0 viene rilevato nel codice del modello, dove il significato di 0 non è chiaro.
    Risposta: Utilizzare un tratto di tipo per scoprire se x è un puntatore (caso n. 2) o no (caso n. 1).

    if (is_pointer(x)) 
    
  2. Situazione: p è una variabile logica NULL valori stile C, che è puntatore al valore numerico.
    Risposta: verifica se il puntatore è nullo. In caso contrario, è possibile controllare l'oggetto appuntito.

    if (p == NULL) { /* case 2 */ } 
    else if (*p == 0) { /* case 1 */ } 
    
  3. Situazione: v è un Win32 variante, che è un'unione discriminata utilizzato per implementare le variabili in linguaggi di scripting.
    Risposta: Controllare la chiave discriminante.

    if (v.vt == VT_EMPTY) { /* case 2a */ } 
    else if (v.vt == VT_NULL) { /* case 2b */ } 
    else if (v.vt == VT_I4 && v.lVal == 0) { /* case 1 */ } 
    else if (v.vt == VT_I2 && v.iVal == 0) { /* case 1 */ } 
    // and so on 
    
  4. Situazione: o è un C++ - Rappresentazione ismo della logica NULL valori, come ad esempio boost::optional.
    Risposta: Queste classi C++ per la logica con valore NULL forniscono un modo per rilevare i valori mancanti. Un esempio specifico con boost::optional<int> dimostra che è stato progettato per essere accessibile, proprio come un puntatore:

    boost::optional<int> o; 
    if (!o) { /* case 2 */ } 
    else if (*o == 0) { /* case 1 */ } 
    
+1

Buona risposta, ma non hai menzionato null_ptr. Penso che sia un sostituto molto potente per NULL nel moderno C++. –

+0

@ GeorgeGaál: 'nullptr' è completamente irrilevante a questa domanda. Un valore di puntatore nullo è un valore di puntatore nullo, indipendentemente dal fatto che il codice sorgente abbia usato '0' o' nullptr'. –

1

In realtà dipende da ciò che si confrontano NULL o 0 con ... se si sta confrontando un intero allora NULL dovrebbe funzionare come 0 se si effettua il confronto con un indirizzo 0 funzionerà come NULL.