- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Язык программирования C++. Пятое издание - Стенли Липпман
Шрифт:
Интервал:
Закладка:
Token &Token::operator=(const Token &t) {
// если этот объект содержит строку, a t нет, прежнюю строку следует
// освободить
if (tok == STR && t.tok != STR) sval.~string();
if (tok == STR && t.tok == STR)
sval = t.sval; // нет необходимости создавать новую строку
else
copyUnion(t); // создать строку, если t.tok содержит STR
tok = t.tok;
return *this;
}
Если объединение в левом операнде содержит строку, а объединение в правом — нет, то сначала следует освободить прежнюю старую строку, прежде чем присваивать новое значение члену объединения. Если оба объединения содержат строку, для копирования можно использовать обычный оператор присвоения класса string. В противном случае происходит вызов функции copyUnion(), осуществляющей присвоение. В функции copyUnion(), если правый операнд — строка, создается новая строка в члене объединения левого операнда. Если ни один из операндов не будет строкой, то достаточно обычного присвоения.
Упражнения раздела 19.6Упражнение 19.21. Напишите собственную версию класса Token.
Упражнение 19.22. Добавьте в класс Token член типа Sales_data.
Упражнение 19.23. Добавьте в класс Token конструктор перемещения и присвоения.
Упражнение 19.24. Объясните, что происходит при присвоении объекта класса Token самому себе.
Упражнение 19.25. Напишите операторы присвоения, получающие значения каждого типа в объединении.
19.7. Локальные классы
Класс, определенный в теле функции, называют локальным классом (local class). Локальный класс определяет тип, видимый только в той области видимости, в которой он определен. В отличие от вложенных классов, члены локального класса жестко ограничены.
Все члены локального класса, включая функции, должны быть полностью определены в теле класса. В результате локальные классы гораздо менее полезны, чем вложенные.
На практике требование полностью определять члены в самом классе, существенно ограничивает сложность, а следовательно, и возможности функций-членов локального класса. Функции локальных классов редко имеют размер, превышающий несколько строк кода. Более длинный код функций труднее прочитать и понять.
Кроме того, в локальном классе нельзя объявлять статические переменные-члены, поскольку нет никакого способа определить их.
Локальные классы не могут использовать переменные из области видимости функцииЛокальный класс может обращаться далеко не ко всем именам из окружающей области видимости. Он может обращаться только к именам типов, статических переменных (см. раздел 6.1.1) и перечислений, определенных в окружающей локальной области видимости. Локальный класс не может использовать обычные локальные переменные той функции, в которой определен класс:
int a, val;
void foo(int val) {
static int si;
enum Loc { a = 1024, b }; // Bar локальна для foo
struct Bar {
Loc locVal; // ok: используется локальное имя типа
int barVal;
void fooBar(Loc l = a) // ok: аргумент по умолчанию Loc::a
{
barVal = val; // ошибка: val локален для foo
barVal = ::val; // ok: используется глобальный объект
barVal = si; // ok: используется статический локальный объект
locVal = b; // ok: используется перечислитель
}
};
// ...
}
К локальным классам применимы обычные правила доступаСодержащая функция не имеет никаких специальных прав доступа к закрытым членам локального класса. Безусловно, локальный класс вполне может сделать содержащую функцию дружественной. Как правило, локальный класс определяет свои члены как открытые. Та часть программы, которая может обращаться к локальному классу, весьма ограниченна. Локальный класс сосредоточен (инкапсулирован) в своей локальной области видимости. Дальнейшая инкапсуляция, подразумевающая сокрытие информации, безусловно, является излишней.
Поиск имен в локальном классеПоиск имен в теле локального класса осуществляется таким же образом, как и у остальных классов. Имена, используемые в объявлениях членов класса, должны быть объявлены в области видимости до их применения. Имена, используемые в определениях членов, могут располагаться в любой части области видимости локального класса. Поиск имен, не найденных среди членов класса, осуществляется сначала в содержащей локальной области видимости, а затем вне области видимости, заключающей саму функцию.
Вложенные локальные классыВполне возможно вложить класс в локальный класс. В данном случае определение вложенного класса может располагаться вне тела локального класса. Однако вложенный класс следует определить в той же локальной области видимости, в которой определен локальный класс:
void foo() {
class Bar {
public:
// ...
class Nested; // объявление класса Nested
};
// определение класса Nested
class Bar::Nested {
// ...
};
}
Как обычно, при определении члена вне класса следует указать область видимости имени. Следовательно, определение Bar::Nested означает класс Nested, определенный в пределах класса Bar.
Класс, вложенный в локальный класс, сам является локальным классом, со всеми соответствующими ограничениями. Все члены вложенного класса должны быть определены в теле самого вложенного класса.
19.8. Возможности, снижающие переносимость
Для поддержки низкоуровневого программирования язык С++ определяет набор средств, применение которых снижает переносимость приложений. Непереносимое (nonportable) средство специфично для определенных машин. Использующие такие средства программы зачастую требуют переделки кода при переносе с одной машины на другую. Одной из причин невозможности переноса является тот факт, что размеры арифметических типов на разных машинах разные (см. раздел 2.1.1).
В этом разделе рассматриваются два дополнительных средства, снижающих переносимость, унаследованных языком С++ от языка С: речь идет о битовых полях и спецификаторе volatile. Также будут рассмотрены директивы компоновки, которые тоже снижают переносимость.
19.8.1. Битовые поля
Класс может определить (нестатическую) переменную-член как битовое поле (bit-field). Битовое поле хранит определенное количество битов. Обычно битовые поля используются при необходимости передать двоичные данные другой программе или аппаратному устройству.
Расположение в памяти битовых полей зависит от конкретной машины.
У битового поля должны быть целочисленный тип или тип перечисления (см. раздел 19.3). Для битового поля обычно используют беззнаковый тип, поскольку поведение битового поля знакового типа зависит от реализации. Чтобы объявить член класса битовым полем, после его имени располагают двоеточие и константное выражение, указывающее количество битов:
typedef unsigned int Bit;
class File {
Bit mode: 2; // mode имеет 2 бита
Bit modified: 1; // modified имеет 1 бит
Bit prot_owner: 3; // prot_owner имеет 3 бита
Bit prot_group: 3; // prot_group имеет 3 бита
Bit prot_world: 3; // prot_world имеет 3 бита
// функции и переменные-члены класса File
public:
// режимы файла определены как восьмеричные
// литералы; см. p. 2.1.3
enum modes { READ = 01, WRITE = 02, EXECUTE = 03 };
File &open(modes);
void close();
void write();
bool isRead() const;
void setWrite();
}
Битовое поле mode имеет размер в два бита, битовое поле modified — только один, а другие — по три бита. Битовые поля, определенные в последовательном порядке в теле класса, если это возможно, упаковываются в смежных битах того же целого числа. Таким образом достигается уплотнение хранилища. Например, пять битовых полей в приведенном выше объявлении будут сохранены в одной переменной типа unsigned int, ассоциированной с первым битовым полем mode. Способ упаковки битов в целое число зависит от машины.
К битовому полю не может быть применен оператор обращения к адресу (&), поэтому не может быть никаких указателей на битовые поля классов.

