Стандарты программирования на С++. 101 правило и рекомендация | страница 88



Исключения

Некоторые компонентные архитектуры (например, COM или CORBA) не используют стандартный механизм удаления и применяют для этого различные собственные протоколы освобождения объектов. Следуйте шаблонам и идиомам этих архитектур и соответствующим образом адаптируйте данную рекомендацию.

Рассмотрим также еще один редкий случай.

• В одновременно является как базовым классом, так и конкретным классом, для которого могут создаваться объекты (так что деструктор этого класса должен быть открытым, чтобы было можно создавать и уничтожать объекты данного типа).

• У В нет виртуальных функций, и он не предназначается для полиморфного использования (так что хотя деструктор и открыт, он не обязан быть виртуальным).

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

В этом редком случае вы можете сделать конструктор открытым и невиртуальным, но четко документировать, что производные объекты не могут использоваться полиморфно в качестве объектов базового класса. Именно это было сделано в случае класса >std::unary_function.

В общем случае, однако, следует избегать конкретных базовых классов (см. рекомендацию 35). Например, >unary_function представляет собой набор определений >typedef, который не предназначен для создания объектов данного типа. В действительности бессмысленно давать ему открытый деструктор; лучше было бы последовать совету данной рекомендации и сделать его деструктор защищенным и невиртуальным.

Ссылки

[Cargill92] pp. 77-79, 207 • [Cline99] §21.06, 21.12-13 • [Henricson97] pp. 110-114 • [Koenig97] Chapters 4,11 • [Meyers97] §14 • [Stroustrup00] §12.4.2 • [Sutter02] §27 • [Sutter04] § 18

51. Деструкторы, функции освобождения ресурсов и обмена не ошибаются

Резюме

Все запуски этих функций должны быть успешными. Никогда не позволяйте ошибке выйти за пределы деструктора, функции освобождения ресурса (например, оператора delete) или функции обмена. В частности, типы, деструкторы которых могут генерировать исключения, категорически запрещено использовать со стандартной библиотекой С++.

Обсуждение

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