2011-10-21 13 views
12

Whey non è possibile Convertire il puntatore in un carattere -> TO-> un riferimento a un puntatore a un carattere costanteC++, necessario Motivo dell'errore: impossibile convertire il parametro 1 da 'char *' a 'const char * &'

Sono interessato a conoscere il motivo dell'errore di sintassi quando chiamiamo foo_ptr. Quando foo_char è permesso perché no foo_ptr.
[Aggiornamento 1.] Sarei felice di conoscere il motivo per cui foo_char() funziona, perché foo_ptr() non funziona .. Cosa succede quando il puntatore entra nell'immagine.

[Aggiornamento 2.] non ha funzionato nel Dev C++ Compiler versione 4.9.9.2 troppo ..

//code 
//OS : Win XP 
//Env: VC++ 2008 

//NOT ALLOWED 
void foo_ptr(const char * & ptr) //reference to a pointer to a constant character   
{   
     return;   
}   


//allowed   
void foo_char(const char & p_Char) //reference to a constant character   
{   
     return;   
}   

int main()   
{   
     char ch = 'd';   
     char *ptr = "anu";   

     foo_char(ch);   
     foo_ptr(ptr); //NOT ALLOWED syntax error, vc++, 2008   

     return 0;   
}   
+0

Forse il parser è sbagliato, prova 'foo_ptr ((const char *) & ptr'. – RedX

+1

Tutto compilato bene su VC2010 Forse un bug corretto? – atoMerz

+0

@RedX: Grazie per gli input, void foo_ptr ((const char *) & ptr) ha dato l'errore C2065: identificato non identificato – anubhav16

risposta

2

Revisionato con altri esempi: Raymond Chen fornisce la risposta corretta. Passando un puntatore non const (char *) come parametro di riferimento di un puntatore const (foo_ptr(const char * &param)) si rischia di restituire un tipo di puntatore const (const char *) e il compilatore non consente di farlo.

Ecco Raymond Chen s' esempio di questo, ma ho cercato di spiegare come le cose sarebbero andare male se compilato con l'aggiunta di commenti aggiuntivi e il codice:

void foo_ptr(const char * & ptr) 
{   
    //Valid assignment, and the char * is now pointing to a const 
    //array of "readonlystring" 
    ptr = "readonlystring"; 
} 

... 
//inside main 
char *ptr = malloc(10*sizeof(char)); 
//See you can edit ptr, it's not const. 
ptr[0] = 'a'; 
ptr[1] = 'b'; 
//this should not compile, but lets assume it did.. 
foo_ptr(ptr); 
//Oh no, now ptr[0] is 'r' inside of constant memory, 
//but now since ptr isn't declared const here I can overwrite it! 
//But luckily most (all?) compilers actually fail to compile this code. 
ptr[0] = 'b'; 

Ma se si cambia il parametro di così non si può influenza il valore indicato dal puntatore, quindi il compilatore ti lascerà passare in un non-const perché non c'è alcuna possibilità che venga restituito un puntatore a valore const.

Inserendo la parola chiave const DOPO * nella decelerazione dei parametri, si fa proprio così. Ciò significa che il cambiamento:

void foo_ptr(const char * & ptr) 

a

void foo_ptr(const char * const & ptr) 

e il compilatore saranno felici.

Ora non sareste in grado di fare qualcosa come ptr = "readonlystring" nell'esempio sopra perché non sarebbe mai compilato ora.In base alla tua domanda, dovrebbe essere corretto perché non potresti eseguire l'assegnazione a const char & nell'esempio originale.

+0

Eric e @James: Grazie mille ragazzi. Per me, questo suona meglio di ogni altra risposta qui [almeno al mio understaning]. Sono alle prime armi e sarebbe davvero utile se un piccolo dettaglio nella spiegazione con l'esempio (s) può essere aggiunto qui per aiutarci a capire completamente. (o qualsiasi sorgente/collegamento funzionerebbe allo stesso modo). .... ho dato un sacco di pensiero sulla linea ".... puntatore di array const si rischia di restituire un tipo di puntatore const" .. ma non poteva sentirsi soddisfatto .. Grazie mille per il tempo e lo sforzo. – anubhav16

+0

Ho rivisto la risposta con qualche altro codice e spiegazione. Spero che i frammenti che ho aggiunto per spiegare la linea che ti ha confuso ti aiuteranno. – James

+0

Ottimo .. io ora .. capito. Molte grazie :). Apprezzo gli sforzi e il tempo che hai dedicato. Molte grazie ancora. – anubhav16

0

Non si dovrebbe mai assegnare una stringa letterale ad un non constchar puntatore, come si fa qui:

char *ptr = "anu";   

Modificare il precedente per correggere il codice:

const char *ptr = "anu";   

... e penso che troverai i tuoi problemi risolti.

+7

Ma questo non risponde alla sua domanda: – Nawaz

+0

grazie per il tempo, ma Sì, questo non ha risposto alla mia domanda.Se 'const' era stata l'unica preoccupazione, come ha funzionato per foo_char? – anubhav16

10

Supponete di avere

void foo_ptr(const char * & ptr) 
{   
    ptr = "readonlystring"; 
}   

Ora chiami come

char *ptr; 
    foo_ptr(ptr); 
    *ptr = 0; 

Supponiamo che nessun errore sono state sollevate. Stai scrivendo su una stringa di sola lettura, violando il sistema dei tipi senza alcun cast.

Questa è fondamentalmente la versione CV di How come a pointer to a derived class cannot be passed to a function expecting a reference to a pointer to the base class?.

+0

Buon punto. fallo comunque con 'typedef char * CHARPTR' . –

+1

Non sai cosa intendi Cambiando' char * ptr' in 'CHAR PTR ptr' avrebbe comunque generato un errore. –

+0

Qual è l'errore? La sostituzione di 'char *' w/typedef nel codice OP dovrebbe essere eseguita correttamente. –