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)

... заставляет работать.