Защищенные данные базового класса открыты для всех производных классов, но закрыты для всех других классов программы. Но даже производные классы не могут получить доступ к закрытым данным и функциям базового класса.
Конструкторы могут инициализироваться до выполнения тела конструктора. При этом вызывается конструктор базового класса, и туда могут быть переданы данные в виде параметров.
Функции, объявленные в базовом классе, могут быть замещены в производных классах. Если при этом функция объявлена как виртуальная, а обращение к функции от объекта осуществляется с помощью указателя на объект или ссылки, то вызываться будет тот замещенный вариант функции, который соответствует типу текущего объекта.
Методы базового класса можно вызывать явным обращением, когда в строке вызова сначала указывается имя базового класса с двумя символами двоеточия после него. Например, если класс 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. Как вызвать функцию базового класса из объекта производного класса, если в производном классе эта функция была замещена?
Читать дальше