- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания Освой самостоятельно за 21 день - Джесс Либерти
Шрифт:
Интервал:
Закладка:
19: Mammal speak!
Анализ: Листинг 11.11 похож на два предыдущих листинга, однако в данной программе в классе Mammal добавлен один новый виртуальный метод — Clone(). Этот метод возвращает указатель на новый объект класса Mammal, используя конструктор-копировщик, параметр которого представлен указателем <<this.
Метод Clone() замещается в обоих производных классах — Dog и Cat — соответствующими версиями, после чего копии данных передаются на конструкторы- копировщики производных классов. Поскольку Clone() является виртуальной функцией, то в результате будут созданы виртуальные конструкторы-копировщики, как показано в строке 81.
Пользователю предлагается выбрать объект класса 0og, Cat или Mammal. Объект выбранного типа создается в строках 62-74. В строке 75 указатель на новый объект добавляется в массив данных.
Затем осуществляется цикл, в котором для каждого объекта массива вызываются методы Speak() и Clone() (см. строки 80 и 81). В результате выполнения функции возвращается указатель на копию объекта, которая сохраняется в строке 81 во втором массиве.
В строке 1 вывода на экран показан выбор пользователем опции 1 — создание объекта класса Dog. В создание этого объекта вовлекаются конструкторы базового и производного классов. Эта операция повторяется для объектов классов Cat и Mammal в строках вывода 4-8.
В строке 9 вывода показано выполнение метода Speak() для объекта класса Dog. Поскольку функция Speak() также объявлена как виртуальная, то при обращении к ней вызывается та ее версия, которая соответствует типу объекта. Затем следует обращение еще к одной виртуальной функции Clone(), виртуальность которой проявляется в том, что при вызове из объекта класса Dog запускаются конструктор класса Mammal и конструктор-копировщик класса Dog.
То же самое повторяется для объекта класса Cat (строки вывода с 12—14) и объекта класса Mammal (строки вывода 15 и 16). В результате создается массив объектов, для каждого из которых вызывается своя версия функции Speak().
Цена виртуальности методов
Поскольку объекты с виртуальными методами должны поддерживать v-таблицу, то использование виртуальных функций всегда ведет к некоторому повышению затрат памяти и снижению быстродействия программы. Если вы работаете с небольшим классом, который не собираетесь делать базовым для других классов, то в этом случае нет никакого смысла использовать виртуальные методы.
Объявляя виртуальный метод в программе, заплатить придется не только за v- таблицу (хотя добавление последующих записей потребует не так уж много места), но и за создание виртуального деструктора. Поэтому следует подумать, имеет ли смысл преобразовывать методы программы в виртуальные, а если да, то какие именно.
Рекомендуется:Используйте виртуальные методы только в том случае, если программа содержит базовый и производные классы. Используйте виртуальный деструктор, если в программе были созданы виртуальные методы.
Не рекомендуется:Не пытайтесь создать виртуальный конструктор.
Резюме
Сегодня вы узнали, как наследовать новые классы от базового класса. В этой главе рассматривалось наследование с ключевым словом public и использование виртуальных функций. Во время наследования в производные классы передаются все открыты e и защищенные данные и функции из базового класса.
Защищенные данные базового класса открыты для всех производных классов, но закрыты для всех других классов программы. Но даже производные классы не могут получить доступ к закрытым данным и функциям базового класса.
Конструкторы могут инициализироваться до выполнения тела конструктора. При этом вызывается конструктор базового класса, и туда могут быть переданы данные в виде параметров.
Функции, объявленные в базовом классе, могут быть замещены в производных классах. Если при этом функция объявлена как виртуальная, а обращение к функции от объекта осуществляется с помощью указателя на объект или ссылки, то вызываться будет тот замещенный вариант функции, который соответствует типу текущего объекта.
Методы базового класса можно вызывать явным обращением, когда в строке вызова сначала указывается имя базового класса с двумя символами двоеточия после него. Например, если класс Dog произведен от класса Mammal, то к методу базового класса напрямую можно обратиться следующим выражением: Mammal::walk().
Если в классе используются виртуальные методы, то следует объявить также и виртуальный деструктор. Он необходим для того, чтобы быть уверенным в удалении части объекта, относящейся к производному классу, если удаление объекта осуществлялось с помощью указателя базового класса. Нельзя создать виртуальный конструктор. В то же время можно создать виртуальный конструктор-копировщик и эффективно его использовать с помощью виртуальной функции, вызывающей конструктор-копировщик.
Вопросы и ответы
Наследуются ли данные и функции-члены базового класса в последующие поколения производных классов? Скажем, если класс Dog произведен от класса Mammal, а класс Mammal произведен от класса Animals, унаследует ли класс Dog данные и функции класса Animals?
Да. Если последовательно производить ряд классов, последний класс в этом ряду унаследует всю сумму данных и методов предыдущих базовых классов.
Если в предыдущем примере в классе Mammal будет замещена функция, описанная в классе Animals, то какой вариант функции получит класс Dog?
Если класс Dog наследуется от класса Mammal, то он получит функцию в том виде, в каком она существует в классе Mammal, т.е. замещенную.
Можно ли в производном классе описать как private функцию, которая перед этим была описана в базовом классе как public?
Можно. Функция может быть не только защищена в производном классе, но и закрыта. Она останется закрытой для всех последующих классов, произведенных от этого.
В каких случаях не следует делать функции класса виртуальными?
Описание первой виртуальной функции вызовет создание v-таблицы, что потребует времени и дополнительной памяти. Последующее добавление виртуальных функций будет тривиальным. Многие программисты увлекаются созданием виртуальных функций и полагают, что если в программе есть уже одна виртуальная функция, то и все другие должны быть виртуальными. В действительности это не так. Создание виртуальных функций всегда должно отвечать решению конкретных задач.
Предположим, что некоторая функция без параметров была описана в базовом классе как виртуальная, а затем перегружена таким образом, чтобы принимать один и два целочисленных параметра. Затем в производном классе был замещен вариант функции с одним целочисленным параметром. Что произойдет, если с помощью указателя, связанного с объектом производного класса, вызвать вариант функции с двумя параметрами?
Замещение в производном классе варианта функции с одним параметром скроет от объектов этого класса все остальные варианты функции. Поэтому в случае обращения, описанного в вопросе, компилятор покажет сообщение об ошибке.
Коллоквиум
В этом разделе предлагаются вопросы для самоконтроля и укрепления полученных знаний и приводится несколько упражнений, которые помогут закрепить ваши практические навыки. Попытайтесь самостоятельно ответить на вопросы теста и выполнить задания, а потом сверьте полученные результаты с ответами в приложении Г. Не приступайте к изучению материала следующей главы, если для вас остались неясными хотя бы некоторые из предложенных ниже вопросов.
Тест
1. Что такое v-таблица?
2. Что представляет собой виртуальный деструктор?
3. Можно ли объявить виртуальный конструктор?
4. Как создать виртуальный конструктор-копировщик?
5. Как вызвать функцию базового класса из объекта производного класса, если в производном классе эта функция была замещена?
6. Как вызвать функцию базового класса из объекта производного класса, если в производном классе эта функция не была замещена?
7. Если в базовом классе функция объявлена как виртуальная, а в производном классе виртуальность функции указана не была, сохранится ли функция как виртуальная в следующем произведенном классе?
8. С какой целью используется ключевое слово protected?
Упражнения
1. Объявите виртуальную функцию, которая принимает одно целочисленное значение и возвращает void.
2. Запишите объявление класса Square, произведенного от класса Rectangle, который, в свою очередь, произведен от класса Shape.
3. Предположим, что в предыдущем примере объект класса Shape не использует параметры, объект класса Rectangle принимает два параметра (length и width), а объект класса Square — один параметр (length); запишите конструктор для класса Square.