Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
для шпор(печатаем 8 стр на листе).docx
Скачиваний:
1
Добавлен:
01.04.2025
Размер:
2.86 Mб
Скачать

4. Статические компоненты класса. Инициализация статических компонентов класса.

С.288 страуструп

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

Вот переработанный вариант класса Date, сохраняющий семантику умолчательного конструирования, но не опирающийся при этом на глобальные переменные:

class Date

{

intd, т, у;

static Date default date;

public:

Date {int dd=0, intmm=0, intyy=0);

static void set default {int, int, int) ;

};

К статическому члену можно обращаться так же, как и к любому другому. Дополнительно, к нему можно обращаться без указания классового объекта. Вместо этого следует квалифицировать его имя именем класса.

Void f ()

{

Date::set default {4,5,19445) ; //обращение к статической функции

// set_default() класса Date

}

Статические члены — как данные, так и методы — должны быть определены. Ключевое слово static при этом повторять не надо. Вот пример:

Date Date: : defaultdate {16,12,1770) ; //определяем Date:: default date

void Date: : set default {int d, int m, int у) //определяем Date::set_default()

{

default date = Date {d,m,y}; //присваиваем новое значение умолчательной дате

}

5. Наследование. Типы наследования. Виртуальное наследование.

Механизм наследования является способом построения новых абстрактных типов данных. Он обеспечивает создание на основе существующих классов новых классов, обладающих расширенными возможностями. Новый класс заимствует от существующего свойства поведения, и может добавлять новые свойства и поведения, а также переопределять унаследования.

При наследовании порождаемый новый класс называется производным, а те же классы, от которых наследуется, называются базовыми.

Различают непосредственные базовые классы и косвенные.

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

Есть 3 формы наследования – открытая (public), закрытая (private) и защищенная(protected).

Выбор формы наследования определяется отноениями между теми понятиями, которые предоставляют классы.

Открытое моделирует общее – частное.

Защищенное наследование чаще всего моделирует отношения реализация по средствам.

Закрытое наследование чаще всего представляет отношение быть частью.

Виртуа́льное насле́дование (англ. virtual inheritance) в языке программирования C++ — один из вариантов наследования, который нужен для решения некоторых проблем, порождаемых наличием возможности множественного наследования (особенно «ромбовидного наследования»), путем разрешения неоднозначности того, методы которого из суперклассов (непосредственных классов-предков) необходимо использовать. Оно применяется в тех случаях, когда множественное наследование вместо предполагаемой полной композиции свойств классов-предков приводит к ограничению доступных наследуемых свойств вследствие неоднозначности. Базовый класс, наследуемый множественно, определяется виртуальным с помощью ключевого слова virtual.

С.381 страуструп

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

class Employee

{

string first name, family name;

short department;

public:

Employee {const string & name, int dept) ;

virtual void print () const;

}

Ключевое слов virtual указывает, что функция print () символизирует общий интерфейс к набору одноименных функций, определенных в базовом и производных от него классах. Если такие функции действительно определены в производных классах, компилятор гарантирует вызов своего варианта функции print () для каждого объекта классовой иерархии.

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

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

Например:

void Employee: : print () const

{

cout« family _name« ' \/f << department« ' \n ' ;

}

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

Например:

class Manager -.public Employee

{

list<Employee*> group;

short level;

public:

Manager {const strings name, int dept, int Ivl) ;

void print {) const;

}/

void Manager: -.print {) const

{

Employee: -.print {) ;

cout« "\tlevel" « level « ' \n' /

}