Программирование >>  Дополнительные возможности наследования 

1 ... 101 102 103 [ 104 ] 105 106 107 ... 265


Поскольку объекты с виртуальными методами должны поддерживать v-таблицу, то использование виртуальных функций всегда ведет к некоторому повышению затрат памяти и снижению быстродействия программы. Если вы работаете с небольшим классом, который не собираетесь делать базовым для других классов, то в этом случае нет никакого смысла использовать виртуальные методы.

Объявляя виртуальньп! метод в программе, заплатить придется не только за v-таблицу (хотя добавление последующих записей потребует не так уж много места), но и за создание виртуального деструктора. Поэтому следует подумать, имеет ли смысл преобразовывать методы профаммы в виртуальные, а если да, то какие именно.

Рвкомвнуувшся

Используйте виртуальные методы только в том случае, если программа содержит базовый и производные классы. Используйте виртуальный деструктор, если в программе были созданы виртуальные методы.

Нв рвкомвнудвшся

Не пытайтесь создать виртуальный конструктор.

Резюме

Сегодня вы узнали, как наследовать новые классы от базового класса. В этой главе рассматривалось наследование с ключевым словом public и использование виртуальных функций. Во время наследования в производнь;е классы передаются все открь;-тые и защищенные данные и функции из базового класса.

Защищенные данные базового класса открыты для всех производных классов, но закрыты для всех других классов профаммы. Но даже производные классы не могут получить доступ к закрытым данным и функциям базового класса.

Конструкторы могут инициализироваться до выполнения тела конструктора. При этом вызывается конструктор базового класса, и туда могут быть переданы данные в виде параметров.

Функции, объявленные в базовом классе, могут быть замещены в производных классах. Если при этом функция объявлена как виртуальная, а обращение к функции от объекта осуществляется с помощью указателя на объект или ссылки, то вызываться будет тот замещенный вариант функции, который соответствует типу текущего объекта.

Методы базового класса можно вызывать явным обращением, когда в строке вызова сначала указывается имя базового класса с двумя символами двоеточия после него. Например, если класс Dog произведен от класса Mammal, то к методу базового класса напрямую можно обратиться следующим выражением: Mammal: :walk().

Если в классе используются виртуальные методы, то следует объявить также и виртуальный десфуктор. Он необходим для того, чтобы быть уверенным в удалении части объекта, относящейся к производному классу, если удаление объекта осуществлялось с помощью указателя базового класса. Нельзя создать виртуальный консфуктор. В то же время можно создать виртуальный конструктор-копировщик и эффективно его использовать с помощью виртуальной функции, вызывающей консфуктор-копировщик.

�2722112



Вопросы u ответы

Наследуются ли данные и функции-члены базового класса в последующие поколения производных классов? Скажем, если класс 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.

4. Запищите виртуальный конструктор-копировщик для класса Square, взятого из упражнения 3.

5. Жучки: что неправильно в следующем программном коде?

void SomeFunctlon(Shape); Shape * pRect = new Rectangle; SomeFunctlon(*pRect);

6. Жучки: что неправильно в следующем программном коде?

class ShapeO {

public; ShapeO;

virtual -ShapeO;

virtual Shape(const Shape&);



1 ... 101 102 103 [ 104 ] 105 106 107 ... 265

© 2006 - 2025 pmbk.ru. Генерация страницы: 0
При копировании материалов приветствуются ссылки.
Яндекс.Метрика