В стандарте С++ указано следующее о виртуальных функциях, имеющих спецификации исключений:
Если виртуальная функция имеет спецификацию исключения, все декларации, включая определение любой функции, которая переопределяет эту виртуальную функцию в любом производном классе, должны разрешать исключения, допускаемые спецификацией исключения виртуальной функции базового класса (С++ 03 § 15.4/3).
Таким образом, следующее плохо сформировано:
struct B {
virtual void f() throw() { } // allows no exceptions
};
struct D : B {
virtual void f() { } // allows all exceptions
};
(1) Используется ли это правило для деструкторов? То есть следующие хорошо сформированные?
struct B {
virtual ~B() throw() { }
};
struct D : B {
virtual ~D() { }
};
(2) Как это правило применяется к неявно объявленному деструктору? То есть, правильно ли сформирован?
struct B {
virtual ~B() throw() { }
};
struct D : B {
// ~D() implicitly declared
};
В общем случае нужно никогда не писать спецификацию исключения, этот вопрос имеет практические последствия, поскольку деструктор std::exception
является виртуальным и имеет пустая спецификация исключения.
Поскольку это хорошая практика, чтобы не исключать исключение из деструктора, допустим для упрощения любых примеров, которые деструктор либо разрешает все исключения (т.е. не имеет спецификации исключений), либо не допускает (т.е. имеет пустую спецификацию исключения).