- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Язык программирования C++. Пятое издание - Стенли Липпман
Шрифт:
Интервал:
Закладка:
// val1.ival = 0; val1.s = string("Anna")
Data val1 = { 0, "Anna" };
Инициализаторы должны располагаться в порядке объявления переменных-членов. Таким образом, сначала располагается инициализатор для первой переменной-члена, затем для второй и т.д. Следующей пример ошибочен:
// ошибка: нельзя использовать "Anna" для инициализации ival или 1024
// для инициализации s
Data val2 = { "Anna" , 1024 };
Как и при инициализации элементов массива (см. раздел 3.5.1), если в списке инициализаторов меньше элементов, чем переменных-членов класса, последние переменные-члены инициализируются значением по умолчанию. Список инициализаторов не должен содержать больше элементов, чем переменных-членов у класса.
Следует заметить, что у явной инициализации переменных-членов объекта класса есть три существенных недостатка.
• Она требует, чтобы все переменные-члены были открытыми.
• Налагает дополнительные обязанности по правильной инициализации каждой переменной-члена каждого объекта на пользователя класса (а не на его автора). Такая инициализация утомительна и часто приводит к ошибкам, поскольку достаточно просто забыть инициализатор или предоставить неподходящее значение.
• Если добавляется или удаляется переменная-член, придется изменить все случаи инициализации.
Упражнения раздела 7.5.5Упражнение 7.52. На примере первой версии класса Sales_data из раздела 2.6.1 объясните следующую инициализацию. Найдите и исправьте возможные ошибки.
Sales_data item = {"978-0590353403", 25, 15.99};
7.5.6. Литеральные классы
В разделе 6.5.2 упоминалось, что параметры и возвращаемое значение функции constexpr должны иметь литеральные типы. Кроме арифметических типов, ссылок и указателей, некоторые классы также являются литеральными типами. В отличие от других классов, у классов, являющихся литеральными типами, могут быть функции-члены constexpr. Такие функции-члены должны отвечать всем требованиям функций constexpr. Эти функции-члены неявно константные (см. раздел 7.1.2).
Агрегатный класс (см. раздел 7.5.5), все переменные-члены которого имеют литеральный тип, является литеральным классом. Неагрегатный класс, соответствующий следующим ограничениям, также является литеральным классом.
• У всех переменных-членов должен быть литеральный тип.
• У класса должен быть по крайней мере один конструктор constexpr.
• Если у переменной-члена есть внутриклассовый инициализатор, инициализатор для переменной-члена встроенного типа должен быть константным выражением (см. раздел 2.4.4). Если переменная-член имеет тип класса, инициализатор должен использовать его собственный конструктор constexpr.
• Класс должен использовать заданное по умолчанию определение для своего деструктора — функции-члена класса, удаляющего объекты типа класса (см. раздел 7.1.5).
Конструкторы constexprХотя конструкторы не могут быть константными (см. раздел 7.1.4), в литеральном классе они могут быть функциями constexpr (см. раздел 6.5.2). Действительно, литеральный класс должен предоставлять по крайней мере один конструктор constexpr.
Конструктор constexpr может быть объявлен как = default (см. раздел 7.1.4) или как удаленная функция, которые будут описаны в разделе 13.1.6. В противном случае конструктор constexpr должен отвечать требованиям к конструкторам (у него не может быть оператора return) и к функциям constexpr (его исполняемый оператор может иметь единственный оператор return) (см. раздел 6.5.2). В результате тело конструктора constexpr обычно пусто. Определению конструктора constexpr предшествует ключевое слово constexpr:
class Debug {
public:
constexpr Debug(bool b = true): hw(b), io(b), other(b) { }
constexpr Debug(bool h, bool i, bool o):
hw(h), io(i), other(o) { }
constexpr bool any() { return hw || io || other; }
void set_io(bool b) { io = b; }
void set_hw(bool b) { hw = b; }
void set_other(bool b) { hw = b; }
private:
bool hw; // аппаратная ошибка, отличная от ошибки IO
bool io; // ошибка IO
bool other; // другие ошибки
};
Конструктор constexpr должен инициализировать каждую переменную-член. Инициализаторы должны либо использовать конструктор constexpr, либо быть константным выражением.
Конструктор constexpr используется и для создания объектов constexpr, и для параметров или типов возвращаемого значения функций constexpr:
constexpr Debug io_sub(false, true, false); // отладка IO
if (io_sub.any()) // эквивалент if (true)
cerr << "print appropriate error messages" << endl;
constexpr Debug prod(false); // при выпуске без отладки
if (prod.any()) // эквивалент if (false)
cerr << "print an error message" << endl;
Упражнения раздела 7.5.6Упражнение 7.53. Определите собственную версию класса Debug.
Упражнение 7.54. Должны ли члены класса Debug, начинающиеся с set_, быть объявлены как constexpr? Если нет, то почему?
Упражнение 7.55. Является ли класс Data из раздела 7.5.5 литеральным? Если нет, то почему? Если да, то почему он является литеральным.
7.6. Статические члены класса
Иногда классы нуждаются в членах, ассоциированных с самим классом, а не с его индивидуальными объектами. Например, класс банковского счета, возможно, нуждается в переменной-члене, представляющей базовую процентную ставку. В данном случае мы хотели бы ассоциировать процентную ставку с классом, а не с каждым конкретным объектом. С точки зрения эффективности нет никаких причин хранить процентную ставку для каждого объекта. Однако важней всего то, что если процентная ставка изменится, каждый объект сразу использует новое значение.
Объявление статических членовЧтобы сделать член класса статическим, его объявление следует предварить ключевым словом static. Статические члены, как и любые другие, могут быть открытыми или закрытыми. Статическая переменная-член может быть константой, ссылкой, массивом, классом и т.д.
В качестве примера определим класс, представляющий банковскую учетную запись:
class Account {
public:
void calculate() { amount += amount * interestRate; }
static double rate() { return interestRate; }
static void rate(double);
private:
std::string owner;
double amount;
static double interestRate;
static double initRate();
};
Статические члены класса существуют вне конкретного объекта. Объекты не содержат данные, связанные со статическими переменными-членами. Таким образом, каждый объект класса Account будет содержать две переменные-члена — owner и amount. Есть только один объект interestRate, совместно используемый всеми объектами Account.
Аналогично статические функции-члены не связаны с конкретным объектом; у них нет указателя this. В результате статические функции-члены не могут быть объявлены константами и к указателю this нельзя обратиться в теле статического члена класса. Это ограничение применимо и к явному использованию указателя this, и к неявному, при вызове не статического члена класса.
Использование статических членов классаК статическому члену класса можно обратиться непосредственно, используя оператор области видимости:
double r;
r = Account::rate(); // доступ к статическому члену при помощи
// оператора области видимости
Даже при том, что статические члены не являются частью отдельных объектов, для доступа к статическому члену класса можно использовать объект, ссылку или указатель на тип класса:
Account ac1;
Account *ac2 = &ac1;
// эквивалентные способы вызова статической функции
rate r = ac1.rate(); // через объект класса Account или ссылку
r = ac2->rate(); // через указатель на объект класса Account
Функции-члены могут использовать статические члены непосредственно, без оператора области видимости:
class Account {
public:
void calculate() { amount += amount * interestRate; }
private:
static double interestRate; // остальные члены как прежде
};
Определение статических членовПодобно любой другой функции-члену, статическую функцию-член можно определить как в, так и вне тела класса. Когда статический член класса определяется вне его тела класса, ключевое слово static повторять не нужно, оно присутствует только в объявлении в теле класса:

