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

на главную

Жанры

Программирование. Принципы и практика использования C++ Исправленное издание
Шрифт:

Date holiday(1978, Date::jul, 4); // инициализация

Date d2 = holiday;

Date d3 = Date(1978, Date::jul, 4);

holiday = Date(1978, Date::dec, 24); // присваивание

d3 = holiday;

Обозначение

Date(1978, Date::dec, 24)
означает создание соответствующего неименованного объекта класса Date, которое затем можно соответствующим образом использовать. Рассмотрим пример.

cout << Date(1978, Date::dec, 24);

В

данном случае конструктор класса действует почти как литерал. Это часто удобнее, чем сначала создавать переменную или константу, а затем использовать ее лишь один раз.

А если нас не устраивает копирование по умолчанию? В таком случае мы можем либо определить свое собственное копирование (см. раздел 18.2), либо создать конструктор копирования и закрытый оператор копирующего присваивания (см. раздел 14.2.4).

9.7.3. Конструкторы по умолчанию

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

Date::Date(int,Month,int)
, чтобы гарантировать, что каждый объект класса
Date
будет правильно проинициализирован. В данном случае это значит, что программист должен предоставить три аргумента соответствующих типов. Рассмотрим пример.

Date d1; // ошибка: нет инициализации

Date d2(1998); // ошибка: слишком мало аргументов

Date d3(1,2,3,4); // ошибка: слишком много аргументов

Date d4(1,"jan",2); // ошибка: неправильный тип аргумента

Date d5(1,Date::jan,2); // OK: используется конструктор с тремя

// аргументами

Date d6 = d5; // OK: используется копирующий конструктор

Обратите внимание на то, что, даже несмотря на то, что мы определили конструктор для класса

Date
, мы по-прежнему можем копировать объекты класса
Date
. Многие классы имеют вполне разумные значения по умолчанию; иначе говоря, для них существует очевидный ответ на вопрос: какое значение следует использовать, если инициализация не выполнена? Рассмотрим пример.

string s1; // значение по умолчанию: пустая строка ""

vector<string> v1; // значение по умолчанию: вектор без элементов

vector<string> v2(10); // вектор, по умолчанию содержащий 10 строк

Все это выглядит вполне разумно и работает в соответствии с указанными комментариями. Это достигается за счет того, что классы

vector
и
string
имеют конструкторы по умолчанию, которые неявно выполняют желательную инициализацию.

Для типа

T
обозначение
T
— значение по умолчанию, определенное конструктором, заданным по умолчанию.
Итак, можно написать следующий код:

string s1 = string; // значение по умолчанию: пустая строка ""

vector<string> v1 = vector<string>; // значение по умолчанию:

// пустой вектор; без элементов

vector<string> v2(10,string); // вектор, по умолчанию содержащий

// 10 строк

Однако мы предпочитаем эквивалентный и более краткий стиль.

string s1; // значение по умолчанию: пустая строка ""

vector<string> v1; // значение по умолчанию: пустой вектор;

// без элементов

vector<string> v2(10); // вектор, по умолчанию содержащий 10 строк

Для встроенных типов, таких как

int
и
double
, конструктор по умолчанию подразумевает значение
0
, так что запись
int
— это просто усложненное представление нуля, а
double
— долгий способ записать число
0.0
.

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

string s1("Ike"); // объект, инициализированный строкой "Ike"

string s2; // функция, не получающая аргументов и возвращающая

// строку

Использование конструктора, заданного по умолчанию, — это не просто вопрос стиля. Представьте себе, что отказались от инициализации объектов класса

string
и
vector
.

string s;

for (int i=0; i<s.size; ++i) // ой: цикл выполняется неопределенное

// количество раз

s[i] = toupper(s[i]); // ой: изменяется содержание

// случайной ячейки памяти

vector<string> v;

v.push_back("bad"); // ой: запись по случайному адресу

Если значения переменных

s
и
v
действительно не определены, то непонятно, сколько элементов они содержат или (при общепринятом способе реализации; см. раздел 17.5) неясно, где эти элементы должны храниться. В результате будут использованы случайные адреса — и это худшее, что может произойти. В принципе без конструктора мы не можем установить инвариант, поскольку не можем гарантировать, что его объекты будут корректными (см. раздел 9.4.3). Мы настаиваем на том, что такие переменные должны быть проинициализированы. В таком случае фрагмент можно было бы переписать следующим образом:

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

Часовое имя

Щерба Наталья Васильевна
4. Часодеи
Детские:
детская фантастика
9.56
рейтинг книги
Часовое имя

Ох уж этот Мин Джин Хо 4

Кронос Александр
4. Мин Джин Хо
Фантастика:
попаданцы
дорама
5.00
рейтинг книги
Ох уж этот Мин Джин Хо 4

Аутсайдер

Астахов Евгений Евгеньевич
11. Сопряжение
Фантастика:
боевая фантастика
космическая фантастика
постапокалипсис
рпг
5.00
рейтинг книги
Аутсайдер

Вдова на выданье

Шах Ольга
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Вдова на выданье

Блуждающие огни 2

Панченко Андрей Алексеевич
2. Блуждающие огни
Фантастика:
боевая фантастика
космическая фантастика
попаданцы
альтернативная история
фэнтези
5.00
рейтинг книги
Блуждающие огни 2

Кодекс Охотника. Книга VI

Винокуров Юрий
6. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга VI

Волк: лихие 90-е

Киров Никита
1. Волков
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Волк: лихие 90-е

Магия чистых душ

Шах Ольга
Любовные романы:
любовно-фантастические романы
5.40
рейтинг книги
Магия чистых душ

Релокант. По следам Ушедшего

Ascold Flow
3. Релокант в другой мир
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Релокант. По следам Ушедшего

(Не) Все могут короли

Распопов Дмитрий Викторович
3. Венецианский купец
Фантастика:
попаданцы
альтернативная история
6.79
рейтинг книги
(Не) Все могут короли

Изгой Проклятого Клана. Том 2

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

(Бес) Предел

Юнина Наталья
Любовные романы:
современные любовные романы
6.75
рейтинг книги
(Бес) Предел

Отверженный VIII: Шапка Мономаха

Опсокополос Алексис
8. Отверженный
Фантастика:
городское фэнтези
альтернативная история
аниме
5.00
рейтинг книги
Отверженный VIII: Шапка Мономаха

Её (мой) ребенок

Рам Янка
Любовные романы:
современные любовные романы
6.91
рейтинг книги
Её (мой) ребенок