2010-01-29 24 views
9

Ho letto da Wikipedia che:Un riferimento non può essere NULL o può essere NULL?

“References cannot be null, whereas pointers can; every reference refers to some object, although it may or may not be valid.”

Ma io non credo a causa del seguente codice di guardare a questo compilatore dà alcun errore:

class person 
{ 
public: 
virtual void setage()=0; 
}; 
main() 
{ 
person *object=NULL; 
person &object1=*object; 
} 

Si prega di elaborare questo punto.

+7

L'articolo dovrebbe probabilmente dire: "Ogni riferimento in un programma ben formato si riferisce a un oggetto" Il dereferenziamento di un puntatore nullo è ovviamente mal formato. – GManNickG

+0

Penso che volevi dire 'persona & oggetto1 = oggetto;', che ti darà un errore nel compilatore (tipi non corrispondenti). –

+8

E non dimentichiamo tutti la nostra storia preferita sui riferimenti null: http://www.gotw.ca/conv/002.htm – GManNickG

risposta

9

Dire il person &object1=*object non è la stessa cosa di person &object1=NULL. Probabilmente il compilatore non è abbastanza intelligente da scoprire che stai degnando il puntatore nullo, ma otterrai comunque un errore di runtime. Quindi sono ancora piuttosto fermi;)

+0

ok ok ho capito molto chiaramente il tuo punto di vista grazie –

20

Nel codice:

person *object=NULL; 
person &object1=*object; 

si dereference un puntatore NULL, in modo da ottenere un comportamento indefinito. E per rispondere alla tua domanda, non esiste un riferimento NULL.

E per rispondere all'altra parte della domanda, solo perché un programma viene compilato, non vi è alcuna garanzia che sia corretto o che funzioni. I compilatori C++ non sono nemmeno tenuti a tentare di diagnosticare il tipo di errore contenuto nel codice.

2

Bene, si può fare qualsiasi cosa si desidera in C++. Un altro esempio:

person &object1 = *(reinterpret_cast<person*>(0)); 

Stai invocando un comportamento non definito nel caso precedente, accanto al caso che hai menzionato!

+0

Grazie Neil, l'ho corretto. – AraK

+0

C'è un motivo per cui preferisci 'reinterpret_cast' a un' static_cast'? (Si comportano allo stesso modo in questo caso, naturalmente.) – avakar

+0

@avakar Questo è quello che mi è venuto in mente quando ho scritto la risposta :) – AraK

3

che causerebbe il crash del programma. Hai provato a eseguirlo? facendo * l'oggetto deferirà un puntatore nullo, quindi in realtà il tuo riferimento non viene mai assegnato.

+0

risposta eccellente l'ho capito. –

+0

Non credo che andrà in crash. Si arresterebbe in modo anomalo solo se si tenta di accedere a membri (o metodi) di object1. – Julio

+2

Potrebbe arrestarsi in modo anomalo, stampare 42 o emettere fumo blu: la semplice derefissione di un puntatore nullo richiama un comportamento non definito, quindi non è possibile sapere in anticipo. –

3

È possibile avere un riferimento null, non è sicuro del motivo per cui qualcuno direbbe altrimenti, è un brutto effetto collaterale di alcune operazioni. Non puoi crearne uno direttamente.

+0

Non dovrei essere sorpreso di vedere il downvoting, posso sempre dire che cosa farà esplodere le persone stupide del pianeta che pensano di sapere tutto ma non sanno nulla. –

+2

È possibile ottenere riferimenti NULL * in pratica *. Ogni volta che uno dice "tu * non può * avere riferimenti NULL", dovrebbe leggere * in un programma ben formato *. Oltre a dereferenziare i puntatori NULL, potrebbe anche essere possibile creare un riferimento, in modo che '& ref == NULL' eseguendo l'auto-inizializzazione:' int & ref = ref; '(il risultato potrebbe essere qualsiasi cosa, incluso NULL, suppongo). - Non penso che ci sarebbe qualcosa di sbagliato nel coprire l'aspetto pragmatico del problema, ma la tua risposta è vaga, disinformativa e polemica ("nonostante quello che dicono tutti, [un punto un po 'bizzarro qui]"). – UncleBens

+0

@UncleBens, * Null * reference ha connotazioni che non sono supportate dalla lingua. Penso che il riferimento * invalid * descriva meglio la situazione. È una sottile differenza, ma penso che sia meno controversa. –

0

clang 3.5 mette in guardia anche su un eventuale controllo in seguito NULL di riferimento:

/tmp/person.C:11:6: warning: reference cannot be bound to dereferenced null pointer in well-defined C++ code; pointer may be assumed to 
     always convert to true [-Wundefined-bool-conversion] 
if (&object1) {} 
~~ ^~~~~~~ 
1 warning generated. 
Problemi correlati