Александреску Андрей
Шрифт:
Согласно рекомендации 10, следует в первую очередь избегать глобальных и совместно используемых переменных. Но даже если вы благополучно устраните их, некоторый другой код может этого не сделать. Например, некоторые стандартные функции имеют побочные действия (например,
Рецепт очень прост — использовать именованные объекты для того, чтобы обеспечить порядок вычислений (см. рекомендацию 13):
[Alexandrescu00c] • [Cline99] §31.03-05 • [Dewhurst03] §14-15 • [Meyers96] §9-10 • [Stroustrup00] §6.2.2, §14.4.1 • [Sutter00] §16 • [Sutter02] §20-21
Проектирование классов и наследование
Наиболее важный аспект разработки программного обеспечения — ясно понимать, что именно вы пытаетесь построить.
— Бьярн Страуструп (Bjarne Stroustrup)Какого вида классы предпочитает разрабатывать и строить ваша команда? Почему?
Интересно, что большинство рекомендаций данного раздела вызваны в первую очередь вопросами зависимостей. Например, наследование — вторая по силе взаимосвязь, которую можно выразить в C++ (первая — отношение дружбы), и такую сильную связь надо использовать очень осторожно и продуманно.
В этом разделе мы сконцентрируем внимание на ключевых вопросах проектирования классов — как сделать это правильно, как не допустить ошибку, избежать ловушек, и в особенности — как управлять зависимостями.
В следующем разделе мы обратимся к Большой Четверке специальных функций — конструктору по умолчанию, копирующему конструктору, копирующему присваиванию и деструктору.
В этом разделе мы считаем самой важной рекомендацию 33 — "Предпочитайте минимальные классы монолитным".
32. Ясно представляйте, какой вид класса вы создаете
Существует большое количество различных видов классов, и следует знать, какой именно класс вы создаете.
Различные виды классов служат для различных целей и, таким образом, следуют различным правилам.
Классы-значения (например,
• Имеют открытые деструктор, копирующий конструктор и присваивание с семантикой значения.
• Не имеют виртуальных функций (включая деструктор).
• Предназначены для использования в качестве конкретных классов, но не в качестве базовых (см. рекомендацию 35).
• Обычно размещаются в стеке или являются непосредственными членами другого класса.
Базовые классы представляют собой строительные блоки иерархии классов. Базовый класс обладает следующими свойствами.
• Имеет деструктор, который является либо открытым и виртуальным, либо защищенным и невиртуальным (см. рекомендацию 50), а также копирующий конструктор и оператор присваивания, не являющиеся открытыми (см. рекомендацию 53).
• Определяет интерфейс посредством виртуальных функций.
• Обычно объекты такого класса создаются динамически в куче как часть объекта производного класса и используются посредством (интеллектуальных) указателей.
Говоря упрощенно, классы свойств представляют собой шаблоны, которые несут информацию о типах. Класс свойств обладает следующими характеристиками.
• Содержит только операторы
• Обычно объекты данного класса не создаются (конструкторы могут быть заблокированы).
Классы стратегий (обычно шаблоны) являются фрагментами сменного поведения. Классы стратегий обладают следующими свойствами.
• Могут иметь состояния и виртуальные функции, но могут и не иметь их.
• Обычно объекты данного класса не создаются, и он выступает в качестве базового класса или члена другого класса.
Классы исключений представляют собой необычную смесь семантики значений и ссылок. При генерации исключений они передаются по значению, но должны перехватываться по ссылке (см. рекомендацию 73). Классы исключений обладают следующими свойствами.