Почему C ++ std :: exception :: what член const? - PullRequest
4 голосов
/ 25 ноября 2010

Мне интересно, почему функция-член std::exception::what имеет значение const?

class exception 
{
public:
  exception() throw() { }
  virtual ~exception() throw();

  /** Returns a C-style character string describing the general cause
   *  of the current error.  */
  virtual const char* what() const throw();
};

Ответы [ 4 ]

17 голосов
/ 25 ноября 2010

Вызов функции-члена what() не должен изменять наблюдаемое состояние объекта exception.

Как правило, исключения отлавливаются константной ссылкой. Например,

try {
    // ...
}
catch (const std::exception& ex) {
    std::cout << ex.what();
}

Если бы функция-член what() не была константной, этот шаблон не работал бы, потому что вы не смогли бы вызвать его из блока catch.

Если вы не хотите генерировать строку, возвращаемую из what(), до тех пор, пока она не будет вызвана, вы можете материализовать строку в переменную-член переменной.

4 голосов
/ 25 ноября 2010

Поскольку он не изменяет экземпляр Exception.

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

3 голосов
/ 25 ноября 2010

Переверните вопрос.Почему бы это не было const?

Если бы это было "char * what () const", вы могли бы изменить внутренний массив символов, на который what () возвращает указатель.Было бы поразительно глупо для exception () позволять произвольному коду манипулировать своими внутренними буферами таким образом, так что what () возвращает const char * вместо char *.

И если бы это было "const char * what () ", без квалификатора const, это будет означать, что вызов what () изменит внутреннее состояние исключения.Что это не так, и чего вы не ожидаете от этого.

Итак, мы имеем то, что имеем, «const char * what () const».Константная функция, возвращающая указатель на константный массив.И в результате вы можете вызвать его по константной ссылке.Обычно это исключения.

В конце концов, вы обычно не меняете исключения, вы создаете их, бросаете их, а затем управляющий код манипулирует ими, не изменяя их.Таким образом, их функции-члены должны быть постоянными.

2 голосов
/ 25 ноября 2010

Рассуждения, вероятно, исходили из желания поддержать стабильность.Например, может возникнуть исключение, если процессу не хватает памяти.Если это так, было бы контрпродуктивно изменять «что», чтобы ему могло потребоваться больше места.Если программист попытается это сделать, то при таких обстоятельствах он немедленно прервет всю программу.Вероятно, не то, что вы намеревались.

Точно так же не подходит для того, что использовать дополнительное пространство в стеке, поскольку это именно то, что выворачивает во время выброшенного исключения.В библиотеке boost есть исключение boost :: исключение, которое делает , позволяющим вам добавлять к нему материал, поскольку исключение распространяется вверх.Будьте бдительны.

...