puntatori void: differenza tra C e C ++
-
20-09-2019 - |
Domanda
Sto cercando di capire le differenze tra C e C ++ per quanto riguarda puntatori void. le seguenti compilazioni in C, ma non C ++ (tutte le compilazioni fatto con gcc / g ++ -ansi -pedantic -Wall):
int* p = malloc(sizeof(int));
A causa rendimenti malloc
void*
, che C ++ non permette di assegnare a int*
mentre C non consente questo.
Tuttavia, qui:
void foo(void* vptr)
{
}
int main()
{
int* p = (int*) malloc(sizeof(int));
foo(p);
return 0;
}
Sia C ++ e C compilare con nessuna lamentela. Perché?
K & R2 dicono:
Ogni puntatore ad un oggetto può essere convertito nel tipo
void *
senza perdita di informazione. Se il risultato è riconvertito al puntatore originale tipo, il puntatore originale recuperato.
E questa bella somme tutto quello che c'è sulle conversioni void*
in C. Cosa fa C ++ dettame di serie?
Soluzione
In C, conversioni puntatore da e void*
erano sempre implicito.
In C ++, le conversioni da T*
a void*
sono implicite, ma void*
a qualsiasi altra cosa richiede un cast.
Altri suggerimenti
C ++ è più fortemente tipizzato-di C. Molte conversioni, specialmente quelli che implicano una diversa interpretazione del valore, richiedono una conversione esplicita. nuovo operatore C ++ è un modo type-safe per allocare la memoria sul mucchio, senza un cast esplicito.
E 'utile per capire che tipo di puntatore conversioni in realtà non richiedono l'esecuzione di istruzioni della CPU in più. Essi vengono analizzati durante la fase di compilazione per capire le intenzioni dello sviluppatore. void *
è un puntatore opaco. Tutto ciò che dice che il tipo di oggetto appuntito è sconosciuta. C è debolmente tipizzato. Esso consente la conversione diretta tra (void *
) ed eventuali (T*
) implicitamente. C ++ è fortemente tipizzato. Una conversione da (void *
) a (T*
) non sarebbe davvero fare un buon caso di un linguaggio fortemente tipizzato. Ma C ++ dovuto rimanere compatibile con C, quindi si doveva permettere tali conversioni. Il principio guida è quindi: esplicito è meglio che implicita. Quindi, se si desidera convertire un (void*
) a qualche indicazione specifica (T*
), è necessario scrivere esplicitamente che nel codice. La conversione da (T*
) a (void*
) non richiede conversione esplicita poiché non v'è nulla di più si può fare su un (void *) puntatore direttamente (si può chiamare free () però). Quindi (T*
) a (void*
) la conversione è praticamente sicura.