- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Освой самостоятельно за 21 день - Джесс Либерти
Шрифт:
Интервал:
Закладка:
Листинг 10.10. Возвращение безымянного временного объекта
1: // Листинг 10.10.
2: // Возвращение безымянного временного объекта
3:
4: int
5: #include <iostream.h>
6:
7: class Counter
8: {
9: public:
10: Counter();
11: Counter(int val);
12: ~Counter(){ }
13: int GetItsVal()const { return itsVal; }
14: void SetItsVal(int x) { itsVal = x; }
15: void Increment() { ++itsVal; }
16: Counter operator++ ();
17:
18: private:
19: int itsVal;
20:
21: };
22:
23: Counter::Counter():
24: itsVal(0)
25: { }
26:
27: Counter::Counter(intval):
28: itsVal(val)
29: { }
30:
31: CounterCounter::operator++()
32: {
33: ++itsVal;
34: return Counter (itsVal);
35: }
36:
37: int main()
38: {
39: Counter i;
40: cout << "The value of i is" << i.GetItsVal() << endl;
41: i.Increment();
42: cout << "The value of i is" << i.GetItsVal() << endl;
43: ++i;
44: cout << "The value of i is" << i.GetItsVal() << endl;
45: Counter a = ++i;
46: cout << "The value of a: " << a.GetItsVal();
47: cout << " and i: " << i.GetItsVal() << endl;
48: return 0;
49: }
Результат:
The value of i is 0
The value of i is 1
The value of i is 2
The value of a: 3 and i: 3
Анализ: В строке 11 определен новый конструктор, который принимает значение типа int. Данный конструктор выполняется в строках с 27 по 29. Происходит инициализация переменной itsVal значением, переданным в параметре.
Выполнение оператора инкремента в данной программе упрощено. В строке 33 осуществляется приращение переменной itsVal. Затем в строке 34 создается временный объект класса Counter, которому присваивается значение переменной itsVal. Это значение затем возвращается как результат выполнения оператора инкремента.
Подобное решение выглядит более элегантно, но возникает вопрос, для чего вообще нужно создавать временные объекты. Напомним, что создание и удаление временного объекта в памяти компьютера требует определенных временных затрат. Кроме того, если объект i уже существует и имеет правильное значение, почему бы просто не возвратить его? Реализуем эту идею с помощью указателя this.
Использование указателя this
На прошлом занятии уже рассматривалось использование указателя this. Этот указатель можно передавать в функцию-член оператора инкремента точно так же, как в любую другую функцию-член. Указатель this связан с объектом i и в случае разыменовывания возвращает объект, переменная которого itsVal уже содержит правильное значение. В листинге 10.11 показано возвращение указателя this, что снимает необходимость создания временных объектов.
Листинг 10.11. Возвращение указателя this
1: // Листинг 10.11.
2: // Возвращение указателя this
3:
4: int
5: #include <iostream.h>
6:
7: class Counter
8: {
9: public:
10: Counter();
11: ~Counter(){ }
12: int GetItsVal()const { return itsVal; }
13: void SetItsVal(int x) { itsVal = x; }
14: void Increment() { ++itsVal; }
15: const Counter& operator++ ();
16:
17: private:
18: int itsVal;
19:
20: };
21:
22: Counter::Counter():
23: itsVal(0)
24: { };
25:
26: const Counter& Counter::operator++()
27: {
28: ++itsVal;
29: return *this;
30: }
31:
32: int main()
33: {
34: Counter i;
35: cout << "The value of i is " << i.GetItsVal() << endl;
36: i.Increment();
37: cout << "The value of i is " << i.GetItsVal() << endl;
38: ++i;
39: cout << "The value of i is " << i.GetItsVal() << endl;
40: Counter а = ++i;
41: cout << "The value of a: " << a.GetItsVal();
42: cout << " and i: " << i.GetItsVal() << endl;
43: return 0;
44: }
Результат:
The value of i is 0
The value of i is 1
The value of i is 2
The value of a: 3 and i: 3
Анализ: Выполнение оператора приращения в строках с 26 по 30 заменено разыменовыванием указателя this и возвращением текущего объекта. В результате объект класса Counter присваивается новому объекту а этого же класса. Как уже отмечалось выше, если объект класса Counter требует выделения памяти, необходимо заместить конструктор-копировщик. Но в данном случае конструктор- копировщик, заданный по умолчанию, отлично справляется со своими задачами.
Обратите внимание, что возвращаемое значение представляет собой ссылку класса Counter, благодаря чему отпадает необходимость в создании каких-либо дополнительных временных объектов. Ссылка задана как const, поскольку не должна меняться при использовании в функции.
Перегрузка постфиксных операторов
До сих пор рассматривалась перегрузка оператора преинкремента. Что если перегрузить оператор постинкремента? Тут перед компилятором встает проблема: как различить между собой операторы постинкремента и преинкремента. Существует договоренность, что при определении функции оператора постинкремента устанавливается целочисленный параметр. Значение параметра не имеет смысла. Он используется только как флаг, который сообщает, что перед нами оператор постинкремента.
Различия между преинкрементном и постинкрементном
Прежде чем приступить к перегрузке оператора постинкремента, следует четко понять, чем он отличается от оператора преинкремента. Подробно эта тема рассматривалась на занятии 4 (см. листинг 4.3).
Вспомните, преинкремент означает прирастить, затем возвратить значение, а постинкремент — возвратить значение, а потом прирастить.
Точно так же и в нашем примере оператор преинкремента приращивает значение, после чего возвращает объект, а оператор постинкремента возвращает объект с исходным значением. Чтобы проследить этот процесс, нужно создать временный объект, в котором будет сохранено исходное значение, затем выполнить приращение в исходном объекте и вновь вернуть его во временный объект.
Давайте все это повторим еще раз. Посмотрите на следующее выражение:
а = x++;
Если исходно переменная x равнялась 5, то в этом выражении переменной а будет присвоено значение 5, зато переменная x станет равной 6. Если x не просто переменная, а объект, то его оператор постинкремента должен сохранить исходное значение 5
во временном объекте, прирастить значение объекта x до 6, после чего возвратить значение временного объекта и присвоить его объекту а.
Обратите внимание, что, поскольку речь идет о временном объекте, его следует возвращать как значение, а не как ссылку, так как временный объект выйдет из области видимости как только функция возвратит свое значение. В листинге 10.12 показано использование обоих операторов.
Листинг 10.12. Операторы преинкремента и постинкремента
1: // Листинг 10.12.
2: // Возвращение разыменованного указателя this
3:
4: int
5: #include <iostream.h>
6:
7: class Counter
8: {
9: public:
10: Counter();
11: ~Counter(){ }
12: int GetItsVal()const { return itsVal; }
13: void SetItsVal(int x) { itsVal = x; }
14: const Counter& operator++ (); // оператор преинкремента
15: const Counter operator++ (int); // оператор постинкремента
16:
17: private:
18: int itsVal;
19: };
20:
21: Counter::Counter():
22: itsVal(0)
23: { }
24:
25: const Counter& Counter::operator++()
26: {
27: ++itsVal;
28: return *this;
29: }
30:
31: const Counter Counter::operator++(int x)
32: {
33: Counter temp(*this);
34: ++itsVal;
35: return temp;
36: }
37:
38: int main()
39: {
40: Counter i;
41: cout << "The value of i is " << i.GetItsVal() << endl;
42: i++;
43: cout << "The value of i is " << i.GetItsVal() << endl;
44: ++i;
45: cout << "The value of i is " << i.GetItsVal() << endl;
46: Counter а = ++i;
47: cout << "The value of а: " << a.GetItsVal();
48: cout << " and i: " << i.GetItsVal() << endl;
49: а = i++;
50: cout << "The value of а: " << a.GetItsVal();
51: cout << " and i: " << i.GetItsVal() << endl;
52: return 0;
53: }
Результат:
The value of i is 0
The value of i is 1
The value of i is 2
The value of a: 3 and i: 3
The value of a: 3 and i: 4
Анализ: Оператор постинкремента объявляется в строке 15 и выполняется в строках с 31 по 36. Обратите внимание, что в объявлении оператора преинкремента в строке 14 не задан целочисленный параметр x, выполняющий роль флага. При определении оператора постинкремента используется флагх, чтобы указать компилятору, что это именно постинкремент. Значение параметра x нигде и никогда не используется.
Синтаксис перегрузки операторов с одним операндом
Объявление перегруженных операторов выполняется так же, как и функций. Используйте ключевое слово operator, за которым следует сам перегружаемый оператор. В функциях операторов с одним операндом параметры не задаются, за исключением операторов no- стинкремента и постдекремента, в которых целочисленный параметр играет роль флага. Пример перегрузки оператора преинкремента: