2016-04-15 4 views
6

Хорошая или плохая практика делать чистые виртуальные функции noexcept? Я всегда думал, что мы не должны вводить дополнительное ограничение на его классы реализации, что их реализация не должна быть броском, поскольку это может привести к модификации в реализации и ненужным блокам catch try для предотвращения исключения. я думал, что реализация должна решить, может ли функция отмечена как noexcept, а не спецификация исключения должна решить реализацию?хорошая или плохая практика, чтобы сделать чистые виртуальные функции noexcept

Может кто-нибудь, пожалуйста, поправьте меня, если я ошибаюсь здесь?

ответ

8

noexcept не касается реализаций, это о интерфейсе. Является ли абстрактная операция, представленная виртуальной функцией, которая принципиально не может потерпеть неудачу? Тогда сделать виртуальную функцию noexcept. Если операция может потерпеть неудачу теоретически, даже если ни одна из реализаций, которые вы пишете, не может, нет.

6

noexcept является частью спецификации функции-члена, аналогично его возвращаемому типу, списку параметров и классификатору const. Он помогает пользователям функции - очевидно, за счет исполнителей функций.

Если вам нужно предоставить разработчикам больше гибкости, предоставляя пользователям функцию noexcept, создайте пару функций - не виртуальную публичную функцию с noexcept и защищенную виртуальную функцию без noexcept. Сделайте вызов общественной noexcept функции виртуальной реализацию и обработку исключений, чтобы скрыть их от своих абонентов:

class Base { 
protected: 
    virtual void doSomethingImpl() = 0; 
public: 
    void doSomething() noexcept { 
     try { 
      doSomethingImpl(); 
     } catch(...) { 
      // Provide some handling here 
     } 
    } 
}; 

class Derived : public Base { 
    void doSomethingImpl() { 
     ... // Implementers have flexibility to throw here 
    } 
} 
+0

Я бы сказал, что, если вам нужно использовать эту конструкцию, то есть что-то не так с вашим дизайном. Чтобы иметь возможность правильно обрабатывать исключения реализации, базовому классу нужно было бы слишком много знать о его производных классах. – MicroVirus

+0

Я согласен с базовым классом MicroVirus не должен много думать о производных классах, поэтому на первом месте я всегда стесняюсь ставить noexcept, даже если операция выглядит слишком тривиальной. –

+0

@MicroVirus. Что-то вроде этого может быть полезно в качестве защиты от реализаций, которые могут неожиданно возникать в ситуациях когда вы вообще не контролируете реализацию. Мало что вы можете сделать, чтобы обрабатывать исключение * и * продолжать, как будто ничего не произошло, поэтому обработчик исключений должен регистрироваться и помогать остальной части кода законно прекращаться. – dasblinkenlight

Смежные вопросы