const char * как параметр функции в C++

примечание: Я знаю, что есть много вопросов, которые говорили об этом, но я еще новичок, и я не мог понять на примерах.

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

int someFunction(const char * sm);

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

someMemberVar = sm;

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

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

7 ответов


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

функции someFunction принимает строку только для чтения (для простоты, хотя char * может использоваться в множестве других случаев). Передаете ли вы строку readonly в someFunction или нет, параметр рассматривается как доступный только для чтения кодом, выполняемым в контексте этой функции. Таким образом, в рамках этой функции компилятор попытается максимально запретить запись в эту строку. A non-const указатель-это такая попытка пренебречь тегом только для чтения для строки и компилятора, правильно и громко информирует Вас о таком пренебрежении к его типу system;)

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

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


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

не удается преобразовать из const char* to char*

раз ты так говоришь

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

это имеет смысл. Имейте в виду, что const char* фактически то же самое, что char const* - то есть, это указатель на char const и не const указатель в чар! И вы не можете преобразовать указатель в 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

const char* - указатель на константу char:


const char* ptr0; // ptr0 is mutable, *ptr0 is const
char* const ptr1; // ptr1 is const, *ptr1 is mutable

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


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

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

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

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

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


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


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

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