2011-10-21 3 views
12

Serwatka, której nie można przekształcić wskaźnika na znak -> TO-> odniesienie do wskaźnika o stałym znakuC++, Need Przyczyna błędu: nie można przekonwertować parametru 1 z "char *" na "const char *" i "

Jestem zainteresowany poznaniem przyczyny błędu składni, kiedy nazywamy foo_ptr. Kiedy foo_char jest dozwolone, dlaczego nie foo_ptr.
[Aktualizacja 1.] Byłbym szczęśliwy wiedząc, że działa foo_char(), dlaczego foo_ptr() nie działa. Co dzieje się, gdy wskaźnik pojawia się na obrazie.

[Update 2.] nie działał w Dev C++ w wersji 4.9.9.2 też ..

//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

Może parser jest źle, spróbuj 'foo_ptr ((const char *) & ptr' – RedX

+1

Wszystko skompilowane grzywny na VC2010 Może naprawiono błąd – atoMerz

+0

@RedX:..? Dzięki za wejściami, nieważne foo_ptr ((const char *) & ptr) podał błąd C2065: niezadeklarowany zidentyfikowany – anubhav16

Odpowiedz

2

Zaktualizowany z więcej przykładów: Raymond Chen zapewnia poprawną odpowiedź. Przekazując wskaźnik o stałej wartości (char *) jako parametr referencyjny wskaźnika const (foo_ptr(const char * &param)), można zwrócić typ wskaźnika const (const char *), a kompilator nie pozwoli na to.

Oto przykład, że Raymond Chen „s, ale starałem się wyjaśnić, jak to wszystko pójdzie źle, jeśli to opracowany przez dodanie dodatkowych komentarzy i kod: jeśli zmienisz parametr, więc nie można

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'; 

But wpływa na wartość wskazywaną przez wskaźnik, a następnie kompilator przepuści Cię w stanie niestanowiącym, ponieważ nie ma szansy, aby zwrócił wskaźnik o wartości stałej.

Umieszczając słowo kluczowe const PO * w swoim opóźnieniu parametrów, robisz właśnie to. Oznacza to, że zmiana:

void foo_ptr(const char * & ptr) 

do

void foo_ptr(const char * const & ptr) 

i kompilator będzie zadowolony.

Teraz nie byłbyś w stanie zrobić czegoś takiego jak ptr = "readonlystring" w powyższym przykładzie, ponieważ to nigdy nie skompilowałoby się teraz.Na podstawie Twojego pytania powinno być OK, ponieważ nie byłbyś w stanie wykonać przypisania do const char & w oryginalnym przykładzie.

+0

Eric i @ James: Dziękuję bardzo. Dla mnie brzmi to lepiej niż jakakolwiek inna odpowiedź tutaj [przynajmniej dla mojego podszycia]. Jestem nowicjuszem i byłoby naprawdę pomocne, gdyby można było dodać nieco szczegółów w wyjaśnieniach z przykładami, aby pomóc nam to zrozumieć. (lub każde źródło/link również działałoby jednakowo). .... Dałem dużo do myślenia esp na linii "... wskaźnik tablicy const ryzykujesz zwracając typ wskaźnika const" .. ale nie mogłem poczuć się usatysfakcjonowany .. Wielkie dzięki za poświęcony czas i wysiłek. – anubhav16

+0

Poprawiłem odpowiedź, dodając trochę kodu i wyjaśnienia. Mam nadzieję, że pomogą nam opisy, które dodałem do wyjaśnienia linii, która cię pomyliła. – James

+0

Świetne .. teraz ... zrozumiałem. Wielkie dzięki :). Doceniam wysiłki i czas, który spędziłeś. Wielkie dzięki jeszcze raz. – anubhav16

0

Nigdy nie należy przypisać ciąg dosłowny do niebędącego constchar wskazówki, jak to zrobić tutaj:

char *ptr = "anu";   

Zmiana powyższego celu skorygowania kodu:

const char *ptr = "anu";   

... i myślę, że odkryjesz, że twoje problemy zostały rozwiązane.

+7

Ale to nie odpowiada na jego pytanie – Nawaz

+0

dzięki za czas, ale tak, to nie odpowiedziałem na moje pytanie.Jeśli "const" był jedynym problemem, jak to działało dla foo_char? – anubhav16

10

Załóżmy, że miał

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

teraz nazywamy go jako

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

Załóżmy błąd nie zostały podniesione. Piszemy do łańcucha tylko do odczytu, naruszając system typów bez rzutowania.

Jest to zasadniczo wersja CV z 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

Dobra uwaga. Ale możesz zrób to z 'typedef char * CHARPTR' tak czy inaczej –

+1

Nie jesteś pewien co masz na myśli Zmieniając' char * ptr' na 'CHAR PTR ptr "nadal powodowałby błąd. –

+0

Jaki jest błąd? Zastąpienie 'char *' w/typedef w kodzie OP powinno się pomyślnie skompilować. –