const char * как параметр функции в C ++ - PullRequest
6 голосов
/ 30 октября 2009

ПРИМЕЧАНИЕ: я знаю, что об этом говорилось много вопросов, но я все еще новичок, и я не мог понять примеры.

У меня есть прототип функции, который выглядит следующим образом:

int someFunction(const char * sm);

Здесь, как вы знаете, const char * означает, что эта функция может принимать const или неконстантный указатель на char. Я пробовал что-то подобное в теле функции:

someMemberVar = sm;

someMemberVar - это просто указатель на символ. Компилятор выдает ошибку, сообщая мне: не может конвертировать из const char * в char *.

Здесь я не передал константу, поэтому sm или someMemberVar не являются константами. Итак, о какой константе говорит компилятор?

Ответы [ 7 ]

11 голосов
/ 30 октября 2009

Я постараюсь изложить более простыми словами то, что говорят другие:

Функция someFunction принимает строку, предназначенную только для чтения (для простоты, хотя char * может использоваться в других случаях). Независимо от того, передаете ли вы строку только для чтения на someFunction или нет, параметр обрабатывается как доступный только для чтения кодом, выполняемым в контексте этой функции. Следовательно, в рамках этой функции компилятор будет пытаться предотвратить запись в эту строку в максимально возможной степени. Неконстантный указатель - такая попытка игнорировать доступный только для чтения тег к строке, а компилятор справедливо и громко информирует вас о таком игнорировании его системы типов;)

В чем разница между: int someFunction (const char * sm) const {...} и этим: int someFunction (const char * sm) {...}

Первая - это функция, которая принимает параметр только для чтения. Второй const, написанный после закрывающих скобок, действителен только для функций-членов. Он не только принимает параметр только для чтения, но и гарантирует, что не изменит состояние объекта. Обычно это называется константой уровня проектирования.

10 голосов
/ 30 октября 2009

Это не совсем ясно из вашего вопроса, и я подозреваю, что текст ошибки, которую вы даете, на самом деле неверен, и на самом деле гласит:

не может конвертировать из const char* в char*

Так как вы говорите, что

someMemberVar - это просто указатель на символ.

Это имеет смысл. Имейте в виду, что const char* фактически совпадает с char const*, то есть это указатель на const char, а не указатель const на char! И вы не можете преобразовать указатель в T const в указатель на T, потому что это нарушает безопасность типов. Рассмотрим:

const char* a = "abc";
char* b = a; // what you're trying to do
b[0] = 'x';  // if you could do it, you could change const data without casts
4 голосов
/ 30 октября 2009

const char* - указатель на постоянный символ:


const char* ptr0; // ptr0 is mutable, *ptr0 is const
char* const ptr1; // ptr1 is const, *ptr1 is mutable
1 голос
/ 31 октября 2009

В комментарии к одному из других ответов вы сказали:

const char * sm означает, что я могу передать const или не const, так почему C ++ преобразует это автоматически? Тот не имеет смысла для меня.

Между вашим первоначальным вопросом и тем комментарием, я думаю, вы неправильно понимаете, как компилятор обрабатывает типы.

Вы правы, что неконстантный char * можно безопасно привести к const char *. Тем не менее, ваш метод явно принимает const char *. Таким образом, хотя вы можете передать char * в функцию, компилятор просто автоматически приводит аргумент при вызове функции. Фактический код в функции не знает, был ли исходный аргумент постоянным или нет. Компилятор должен идти по фактическому объявлению переменной, которую вы используете, , а не некоторой предыдущей переменной, которая имела то же значение.

Если вы хотите иметь возможность обрабатывать неконстантные char * переменные по-разному (присваивая их), тогда вам нужно определить функцию, которая принимает неконстантные char * переменные.

1 голос
/ 30 октября 2009

Если вы передадите неконстантный указатель на someFunction, он автоматически преобразуется в константный указатель. Таким образом, вы не можете назначить sm на someMemberVar, потому что это нарушит постоянство sm. Вы можете объявить someMemberVar как const char*, и ваш код будет работать, однако вы не сможете изменить то, на что он указывает.

0 голосов
/ 30 октября 2009

В вашем примере sm это const char *, поэтому у someFunction есть контракт с вызывающей стороной, который не будет изменять память, на которую указывает sm.

Но если вы назначите sm для someMemberVar, а someMemberVar не является const char *, вы сможете изменить память, на которую указывает sm, через someMemberVar, и компилятор не позволит вам сделать это.

0 голосов
/ 30 октября 2009

const char * sm - указатель на постоянный символ (или массив). Когда вы пытаетесь присвоить someMemberVar указатель на символ, вы пытаетесь указать ему набор констант символов. Это причина ошибки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...