C ++ исключение - PullRequest
       18

C ++ исключение

0 голосов
/ 20 декабря 2011

Может ли кто-нибудь объяснить мне это определение стандартного исключения в C ++:

virtual const char* what() const throw();

Что означает const throw() в конце?

Ответы [ 3 ]

9 голосов
/ 20 декабря 2011

Это две разные, не связанные вещи.

const означает, что функция-член не будет изменять никакие (не mutable) переменные-члены; это, в свою очередь, означает, что его можно вызывать для const объектов. e.g.:

class Foo {
public:
    void a() const {
        x = 5;  // Compiler error!
    }

    void b() {
        x = 5;  // This is fine
    }

private:
    int x;
};

int main() {
    Foo       p;
    const Foo q;

    p.a();   // This is fine
    p.b();   // This is fine
    q.a();   // This is fine
    q.b();   // Compiler error!
}

throw() является спецификатором исключения . Он заявляет, что эта функция не будет генерировать исключение. Смотрите, например Должен ли я использовать спецификатор исключений в C ++? для обсуждения.

6 голосов
/ 20 декабря 2011

const означает, что функция не изменит никаких членов класса, в который она встроена, throw() является спецификацией исключения; функция обещает не генерировать исключение.

Обратите внимание, что начиная с C ++ 11 спецификация исключений throw устарела по нескольким причинам: списки исключений было слишком сложно поддерживать, в то время как throw(...) был неэкспрессивным, так что throw() была в основном единственной спецификацией в любом случае, и эти спецификации были динамически проверены во время выполнения, что привело к большим накладным расходам и, таким образом, замедлило ваше приложение.

Теперь вы можете смело заменять throw() на noexcept(true) или просто noexcept. Не будет проверок, действительно ли такой метод вызывает исключение - это гарантия, которую вы даете компилятору, а не наоборот. Если выдается исключение, вызывается std::terminate.

2 голосов
/ 20 декабря 2011

Это отдельные выпуски.


Относительно const

Из стандарта (если слишком долго, читать только полужирный части):

Нестатические функции-члены

[...] Нестатическая функция-член может быть объявлена ​​как const, volatile или const volatile. Эти cv-квалификаторы влияет на тип указателя this (9.3.2). Они также влияют на тип функции (8.3.5) функции-члена; функция-член, объявленная const, является функцией-константой , функция-член, объявленная как volatile, является функция volatile и функция-член, объявленная как const volatile, является постоянным членом функция. [...]

Указатель this

[...] В const функции-члене объект, для которого вызывается функция, доступен через const доступ дорожка; следовательно, функция-член const не должна изменять объект и его нестатические члены-данные. [...]

Спецификаторы класса хранения

[...] Изменяемый спецификатор члена данных класса обнуляет спецификатор const, примененный к содержащему объект класса и разрешает модификацию изменяемого члена класса, даже если остальная часть объекта является const (7.1.6.1).

Сводка: функция-член, квалифицированная как const, не может изменять любого члена, который не объявлен mutable. Причина mutable состоит в том, что даже если объект const, такой механизм, как кэширование, может быть реализован; эффективная практика заключается в том, что наблюдаемое поведение объекта не изменяется при вызове функции-члена const.


Относительно throw()

Спецификации исключений [ожидаем. Спецификация]

Объявление функции перечисляет исключения, которые ее функция может прямо или косвенно выдавать, используя спецификация исключения в качестве суффикса своего объявления.

В частности, это спецификация динамического исключения, а

[...] функция, как говорят, допускает исключение типа E, если ее спецификация динамического исключения содержит тип T для какой обработчик типа T будет совпадением (15.3) для исключения типа E.

Другими словами, типы в ( и ) являются исключениями, которые может генерировать эта функция. Однако по некоторым причинам .

не принято использовать непустые спецификации динамических исключений .

Использование throw(), то есть пустого списка исключений, в пре-C ++ 11 было принято практиковать для аннотирования функций, которые никогда не генерируются. Однако, начиная с C ++ 11, текущего стандарта, вместо него следует использовать noexcept.

Также, начиная с C ++ 11,

[Примечание: использование спецификаций динамических исключений не рекомендуется (см. Приложение D). —Конечная записка]

, поэтому используйте noexcept.

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