Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ООП.docx
Скачиваний:
8
Добавлен:
01.07.2025
Размер:
68 Кб
Скачать
☆

2.7 Производные классы

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

Когда один класс наследуется другим, класс, который наследуется, называется базовым классом. Наследующий класс называют производным классом.

Новый класс строится на базе уже существующего с помощью конструкции следующего вида.

class Parent {....};

class Child : [модификатор наследования] Parent {....};

При определении класса-потомка за его именем следует разделитель-двоеточие («:»), затем - необязательный модификатор наследования и имя родительского класса. Модификатор наследования определяет видимость наследуемых переменных и методов для пользователей и возможных потом ков самого класса-потомка. Другим и словами, он определяет, какие права доступа к переменным и методам класса-родителя будут переданы классу-потомку. При реализации наследования область видимости принадлежащих классу данных и методов можно определять выбором ключевого слова private (собственный), public (общедоступный) или protected (защищенный), которые могут произвольно чередоваться внутри описания класса. С двумя первыми модификаторами доступа мы уже знакомы - private описывает закрытые члены класса, доступ к которым имеют только методы-члены этого класса, public предназначен для описания общедоступных элементов, доступ к которым возможен из любого места в программе. Особый интерес представляют элементы, обладающие модификатором доступа protected.

Модификатор protected используется тогда, когда необходимо, чтобы некоторые ч лены базового класса оставались закрытыми, но были бы доступны для производного класса. Модификатор protected эквивалентен private с единственным исключением : защищенные ч лены базового класса доступны для ч ленов всех производных классов этого базового класса. То, как изменяется доступ к элементам базового класса из методов производного класса в зависимости от значения модификаторов наследования, можно видеть в следующей таблице.

2.8 Встраиваемые функции

Рассмотрим пример:

struct _3d

{

double x, y, z;

double mod()

{return sqrt (x*x + y*y +z*z);}

double projection(_3d r)

{return (x*r.x + y*r.y + z*r.z) / mod();}

_3d operator + (_3d b);

};

_3d _3d::operator + (_3d b)

{

_3d c;

c.x = x + b.x;

c.y = y + b.y;

c.z = z + b.z;

return c;

}

Обратим внимание на то, в каком месте описывается тело того или иного метода. Методы mod() и projection() описаны вместе со своими телами непосредственно внутри структуры. Однако можно поступить иначе: поместить прототипы метода внутрь структуры, а определение тела функции – вне структуры, как мы поступили с оператором « +». Первый способ используется для простых и коротких методов, которые в дальнейшем не предполагается изменять. Так поступают отчасти из-за того, что описания классов помещают обычно в файлы заголовков, включаемые затем в прикладную программу с помощью директивы #include. Кроме того, при этом способе машинные инструкции, генерируемые компилятором при обращении к этим функциям, непосредственно вставляются в оттранслированный текст. Это снижает затраты на их исполнение, поскольку выполнение таких методов не связано с вызовом функций и механизмом возврата, увеличивая в свою очередь размер исполняемого кода (то есть такие методы становятся встраиваемыми). Второй способ предпочтительнее для сложных методов. Объявленные таким об разом функции автоматически заменяются компилятором на вызовы подпрограмм , хотя при добавлении ключевого слова inline могут подставляться в текст, как и в первом случае.

Кроме представленного выше способа создания встраиваемых функций (записать тело метода непосредственно в структуре), есть еще один способ :

вставить спецификатор inline перед определением метода.

inline _3d _3d::operator + (_3d b)

{

_3d c;

c.x = x + b.x;

c.y = y + b.y;

c.z = z + b.z;

return c;

}

Теперь оператор « +» станет встраиваемой функцией.

Встраиваемые функции действуют почти так же, как и макроопределения с параметрами, однако имеют ряд преимуществ. Во-первых, inline методы обеспечивают более стройный способ встраивания в программу короткой функции. Во-вторых, компилятор C++ гораздо лучше работает со встраиваемыми функциями, чем с макроопределениями. Важно понимать, что inline не является командой для компилятора, это, скорее, просьба сделать метод встраиваемым. Если по каким-то причинам (например, при наличии в теле функции операторов цикла, switch или goto) компилятор не выполнит запрос, то функция будет откомпилирована как не встраиваемая.