Чтение онлайн

на главную - закладки

Жанры

C++. Сборник рецептов

Когсуэлл Джефф

Шрифт:

Глава 8

Классы

8.0. Введение

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

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

Конечно, классы — это главная особенность С++, которая обеспечивает возможность объектно-ориентированного программирования, и с ними можно выполнять очень много разных действий. Эта глава не содержит рецептов, объясняющих основы классов: виртуальные функции (полиморфизм), наследование и инкапсуляцию. Я полагаю, что вы уже знакомы с этими основными принципами объектно-ориентированного проектирования независимо от используемого языка программирования. Напротив, целью этой главы является описание принципов некоторых механических сложностей, с которыми можно столкнуться при реализации объектно-ориентированного дизайна на С++.

Объектно-ориентированное проектирование и связанные с ним шаблоны проектирования — это обширный вопрос, и имеется большое количество различной литературы на эту тему. В этой главе я упоминаю названия только некоторых шаблонов проектирования, и это шаблоны, для которых возможности C++ обеспечивают элегантное или, возможно, не совсем очевидное решение. Если вы не знакомы с концепцией шаблонов проектирования, я рекомендую прочесть книгу Design Patterns (Addison Wesley), поскольку это полезная вещь при разработке программного обеспечения. Однако для этой главы знание шаблонов проектирования не требуется.

8.1. Инициализация переменных-членов класса

Проблема

Требуется инициализировать переменные-члены, которые имеют встроенные типы, являются указателями или ссылками.

Решение

Для установки начальных значений переменных членов используйте список инициализации. Пример 8.1 показывает, как это делается для встроенных типов, указателей и ссылок.

Пример 8.1. Инициализация членов класса

#include <string>

using namespace std;

class Foo {

public:

 Foo : counter_(0), str_(NULL) {}

 Foo(int c, string* p) : counter_(c), str_(p) {}

private:

 int counter_;

 string* str_;

};

int main {

 string s = "bar";

 Foo(2, &s);

}

Обсуждение

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

встроенных типов, когда они содержат мусор, — значит напрашиваться на проблемы. Но в C++ есть несколько различных способов выполнить инициализацию, и они описываются в этом рецепте.

Простейшими объектами инициализации являются встроенные типы. Работать с

int
,
char
и указателями очень просто. Рассмотрим простой класс и его конструктор по умолчанию.

class Foo {

public:

 Foo : counter_(0), str_(NULL) {}

 Foo(int c, string* p) : counter_(c), str_(p) {}

private:

 int counter_;

 string* str_;

};

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

Члены инициализируются в порядке их указания в объявлении класса, а не в порядке объявления их в списке инициализации.

Используя тот же класс

Foo
, как и в примере 8.1, рассмотрим переменную-член класса.

class Foo {

public:

 Foo : counter_(0), str_(NULL), cls_(0) {}

 Foo(int с, string* p) :

counter_(c), str_(p), cls_(0) {}

private:

 int counter_;

 string* str_;

 SomeClass cls_;

};

В конструкторе по умолчанию

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

Поделиться:
Популярные книги

Имя нам Легион. Том 2

Дорничев Дмитрий
2. Меж двух миров
Фантастика:
боевая фантастика
рпг
аниме
5.00
рейтинг книги
Имя нам Легион. Том 2

Где властвует любовь

Куин Джулия
4. Бриджертоны
Любовные романы:
исторические любовные романы
8.94
рейтинг книги
Где властвует любовь

Враг из прошлого тысячелетия

Еслер Андрей
4. Соприкосновение миров
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Враг из прошлого тысячелетия

Тепла хватит на всех

Котов Сергей
1. Миры Пентакля
Фантастика:
боевая фантастика
космическая фантастика
5.00
рейтинг книги
Тепла хватит на всех

Каторжник

Шимохин Дмитрий
1. Подкидыш
Фантастика:
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Каторжник

Жатва душ. Остров мертвых

Сугралинов Данияр
Фантастика:
боевая фантастика
рпг
5.20
рейтинг книги
Жатва душ. Остров мертвых

Старшеклассник без клана. Апелляция кибер аутсайдера

Афанасьев Семен
1. Старшеклассник без клана. Апелляция аутсайдера
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Старшеклассник без клана. Апелляция кибер аутсайдера

Черный маг императора 3

Герда Александр
3. Черный маг императора
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Черный маг императора 3

Изгой Проклятого Клана

Пламенев Владимир
1. Изгой
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Изгой Проклятого Клана

Ваше Сиятельство

Моури Эрли
1. Ваше Сиятельство
Фантастика:
фэнтези
попаданцы
5.00
рейтинг книги
Ваше Сиятельство

Солнечный корт

Сакавич Нора
4. Все ради игры
Фантастика:
зарубежная фантастика
5.00
рейтинг книги
Солнечный корт

Черный Маг Императора 4

Герда Александр
4. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 4

Черный Маг Императора 9

Герда Александр
9. Черный маг императора
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Черный Маг Императора 9

Младший сын князя. Том 10

Ткачев Андрей Юрьевич
10. Аналитик
Фантастика:
городское фэнтези
аниме
сказочная фантастика
фэнтези
фантастика: прочее
5.00
рейтинг книги
Младший сын князя. Том 10