Const char * vs char * (С++)
Для следующей программы:
int DivZero(int, int, int);
int main()
{
try {
cout << DivZero(1,0,2) << endl;
}
catch(char* e)
{
cout << "Exception is thrown!" << endl;
cout << e << endl;
return 1;
}
return 0;
}
int DivZero(int a, int b, int c)
{
if( a <= 0 || b <= 0 || c <= 0)
throw "All parameters must be greater than 0.";
return b/c + a;
}
Использование char * e даст
завершение вызова после броска экземпляр 'char const *'
В соответствии с С++ Exception Handling решение состоит в использовании const char *.
Дальнейшее чтение из function (const char *) по сравнению с функцией (char *) говорит, что
Тип "String" равен char*', not
const char * '
(это обсуждение в формате C, которое я думаю...)
Дополнительное чтение о переполнении стека char * vs const char * как параметр говорит мне о разнице. Но ни один из них не отвечает на мои вопросы:
- Кажется, что как char *, так и строка * имеют ограничение на количество символов. Правильно ли я?
- Как добавление ключевого слова const в char * устраняет этот предел? Я думал, что единственной целью const является установка флага, который говорит "не поддающийся изменению". Я понимаю, что const char * е означает "указатель, который указывает на немодифицируемый тип char".
Решение этой ошибки заключается в использовании const char * e.
Даже const string * e не работает. (только ради тестирования...)
Может кто-нибудь объяснить, пожалуйста? Спасибо!
Кстати, я на Ubuntu, скомпилированный GCC, на Eclipse.
Ответы
Ответ 1
Почему вы все равно бросаете и ловите строки?
Вы должны бросить и поймать исключения, например. std::runtime_error
Ответ на ваш вопрос заключается в том, что всякий раз, когда вы вставляете строку в кавычки в код, она возвращает нулевую завершенную константу char *
Причина, по которой ваш код не работает, как указано выше, заключается в том, что он неправильный тип, так что catch не поймает то, что вы бросаете. Вы бросаете const char *.
Нет ограничений на количество символов в массиве char, превышающем размер вашего стека/кучи. Если вы ссылаетесь на приведенный вами пример, этот человек создал массив фиксированного размера, поэтому они были ограничены.
Ответ 2
Сообщение, связанное с "Строкой", неверно (и сбивает с толку).
В принципе:
char*
- указатель на неограниченный массив символов. Традиционно мы рассматриваем такой массив как C-строку, если он содержит набор допустимых символов, за которыми следует a \0
. Нет ограничений на размер массива.
const char*
- это указатель на неограниченный массив неизменяемых символов.
string*
- это указатель на объект std::string
и совершенно другой. Это интеллектуальный объект, который инкапсулирует строку. Использование std::string
вместо C-строк может сделать вашу жизнь легче, хотя у них есть некоторые грубые грани и много неприятных ошибок; они заслуживают внимания, но они не имеют отношения к вопросу.
"String"
- это специальное выражение, которое возвращает const char*
, указывающее на конкретную C-строку (обратите внимание: это на самом деле не правда, но это упрощение, позволяющее мне ответить на вопрос кратко).
A char*
может быть автоматически добавлен к const char*
, но не наоборот. Обратите внимание, что старые компиляторы С++ имели специальное исключение из правил типа, позволяющих вам сделать это:
char* s = "String";
... без возникновения ошибки типа; это было для совместимости с C. Современные компиляторы С++ не позволят вам это делать (например, последние gcc). Они требуют этого:
const char* s = "String";
Итак. Проблема здесь в том, что у вас есть:
throw "All parameters must be greater than 0.";
... но тогда вы пытаетесь поймать его:
catch(char* e)
Это не работает, потому что бросок бросает const char*
, который нельзя отнести к типу, указанному в catch, поэтому он не попадает.
Вот почему изменение улова происходит так:
catch (const char* e)
... заставляет работать.