Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ответы на вопросы Осадчий А.В. гр.010902.docx
Скачиваний:
13
Добавлен:
24.04.2019
Размер:
143.34 Кб
Скачать

29.Переопределение членов базового класса в производном классе.

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

30. Конструкторы и деструкторы в производных классах

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

Поскольку базовый класс ничего не знает про производные от него классы, его инициализация (вызов его конструктора) производится перед инициализацией (активизацией конструктора) производного класса. В противоположность этому деструктор производного класса вызывается перед вызовом деструктора базового класса. Это объясняется тем, что уничтожение объекта базового класса влечет за собой уничтожение и объекта производного класса, следовательно, деструктор производного класса должен выполняться перед деструктором базового класса.

Пример:

class base {

// ...

public:

base(char* n, short t);

~base();

};

class derived : public base {

base m;

public:

derived(char* n);

~derived();

};

Параметры конструктора базового класса специфицируются в

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

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

класса.

Пример:

derived::derived(char* n) : (n,10), m("member",123)

{

// ...

}

Объекты класса конструируются снизу вверх: сначала базовый, потом

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

порядке: сначала сам производный класс, потом члены а потом

базовый.

31. Неявное преобразование объектов производных классов в объекты базового класса. Если конструктор класса А имеет единственный параметр типа В, то объект В может быть неявно преобразован в класс А с помощью такого конструктора. Другими словами, компилятор может сам вызывать такой конструктор, чтобы “из В сделать А”. Локальный объект можно было бы инициализировать по-другому:

class Hold {

char *str;

public:

Hold(const char*);

//...

};

main () {

Hold mainObj = "This is a local object in main.";

//. . .

return 0;

Таким образом, в этом примере объявленный в классе конструктор Hold(const char*) является по сути конструктором преобразования.

Если производный класс derived имеет открытый базовый класс base,

то указатель на derived можно присваивать переменной типа указатель

на base не используя явное преобразование типа. Обратное

преобразование, указателя на base в указатель на derived, должно

быть явным. Пример:

class base { /* ... */ };

class derived : public base { /* ... */ };

derived m;

base* pb = &m; // неявное преобразование

derived* pd = pb; // ошибка: base* не является derived*

pd = (derived*)pb; // явное преобразование

Иначе говоря, объект производного класса при работе с ним через

Указатели можно рассматривать как объект его базового класса.

Обратное неверно.

Будь base закрытым базовым классом класса derived, неявное

преобразование derived* в base* не делалось бы. Неявное

преобразование не может в этом случае быть выполнено, потому что к

открытому члену класса base можно обращаться через указатель на

base, но нельзя через указатель на derived.