2015-11-11 15 views
9

Posso fare questo?Posso trasmettere nullptr ad un altro tipo di puntatore?

static_cast<A*>(getSomePtr()); 

dove getSomePtr() tornerà nullptr. Va bene?

+4

Questo è ciò che 'nullptr' è per. – 101010

+7

Qual è il tipo di ritorno di 'getSomePtr()'?È in realtà 'std :: nullptr_t' o è il valore del puntatore nullo di un tipo di puntatore effettivo? Restituire 'std :: nullptr_t' da una funzione è molto strano, e se non è' std :: nullptr_t', non è necessario lanciarlo perché non è comunque 'nullptr'. –

+0

Ciò che conta è il * tipo *. Il valore di un puntatore non influenza se un cast è valido o meno. – molbdnilo

risposta

12

Da Wikipedia article:

... puntatore nullo costante: nullptr. È del tipo nullptr_t, che è implicitamente convertibile e paragonabile a qualsiasi tipo di puntatore o tipo puntatore-membro. Non è implicitamente trasformabile in o paragonabile a tipi interi, ad eccezione di bool.

nullptr è implicitamente convertibile in qualsiasi tipo di puntatore in modo conversione esplicita con static_cast è assolutamente valida.

+0

Definite "ridondante" come OK? – emlai

+0

@zenith Sto rispondendo alla domanda. La funzione 'getSomePtr()' può restituire 'nullptr', ma a volte il cast può essere utile. L'uso del cast è OK in questo contesto. (Risposta corretta, grazie comunque :) –

0

Sì, puoi farlo. Sarà ancora nullo, quindi non è sicuro chiamare i suoi membri o dati, ma puoi porre domande sulla sua struttura in fase di compilazione.

Ad esempio, questo è un possible implementation of the offsetof(type, member) function in <cstddef>, in cui nullptr viene colato ad un tipo valido:

#define offsetof(type,member) ((std::size_t) &((static_cast<type*>(nullptr))->member)) 
+0

Cosa c'entra "offsetof' con la domanda? Non credo che l'aggiunta chiarisca qualcosa. –

+0

La domanda originale era "Posso lanciare nullptr su un altro tipo di puntatore". L'esempio 'offsetof' mostra che questo può essere fatto, e perché si potrebbe farlo in pratica. –

+0

Questo sta costruendo un oggetto rvalue di tipo 'type *' che è tutta un'altra cosa. Il lancio di 'nullptr' quando si costruiscono i puntatori di rvalue di un tipo specifico è l'unico motivo legittimo per lanciare' nullptr' (non un puntatore nullo). – emlai

7

Sospetto che tu sia confuso sulla differenza tra un puntatore nullo e nullptr, non sono la stessa cosa.

Questa funzione restituisce nullptr:

std::nullptr_t getNullPtr() { return nullptr; } 

Ma questa è una cosa abbastanza inutile ritornare, non v'è molto raramente una buona ragione per restituire un oggetto di quel tipo.

Questa funzione restituisce un puntatore nullo:

A* getAPtr() { return nullptr; } 

Il valore restituito viene inizializzato con nullptr ma in realtà è un puntatore nullo di tipo A*, non nullptr stessa.

Per la prima funzione, sì, è possibile eseguire il cast dello std::nullptr_t restituito a un altro tipo di puntatore (non è nemmeno necessario un cast per eseguire la conversione, si verificherà in modo implicito) ma probabilmente non è qualcosa che si vorrebbe mai fare .

Per la seconda funzione non è necessario eseguire il cast perché restituisce già il tipo corretto.

0

Solo un'aggiunta alle risposte date finora, ma generalizzando la tua domanda un po '(sul casting dei valori di ritorno, vedi le altre risposte): la trasmissione nullptr esplicitamente non è solo valida, ci sono alcune situazioni in cui persino è inevitabile! Ad esempio, se ci sono diverse funzioni sovraccaricate, ognuno di loro accettare un diverso tipo di puntatore ed è necessario (per qualsiasi ragione) chiamare uno di loro con nullptr ...

void f(int*) { /*...*/ } 
void f(double*) { /*...*/ } 
void g() 
{ 
    f(nullptr); // compilation error, ambiguous call! 
    f(static_cast<int*>(nullptr)); // now compiler knows... 
} 
Problemi correlati