Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Билеты по ООП.doc
Скачиваний:
4
Добавлен:
14.04.2019
Размер:
596.48 Кб
Скачать

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

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

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

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

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

Когда базовый класс имеет конструктор с аргументами, производные классы должны передавать базовому классу необходимые аргументы. Для этого используется расширенная форма конструкторов производных классов.

порождённый_конструктор(список_аргументов): базовый1(список_аргументов), базовый2(список_аргументов), …, базовыйN(список_аргументов)

{...};

Здесь под базовый1, базовый2, …, базовыйN обозначены имена базовых классов, наследуемые производным классом. Обратим вниманием, что с помощью двоеточия конструктор производного класса отделяется от списка конструкторов базового класса. Список аргументов, ассоциированный с базовыми классами, может состоять из констант, глобальных переменных или параметров конструктора производного класса.

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

В общем случае указатель одного типа не может указывать на объект другого типа. Из этого правила есть исключение, которое относится только к производным классам. В С++ указатель на базовый класс может указывать на объект производного класса. Ссылки на базовый класс могут быть использованы для ссылок на объект производного типа.

31. Виртуальные функции

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

Пример использования виртуальных функций

#include <iostream>

using namespace std;

class Base {

public:

virtual void who(){// определение виртуальной функции

cout << "Base\n";

}

};

class first_d: public Base {

public:

void who(){// определение who применительно к first_d

cout << "First derivation\n";

}

};

class second_d: public Base {

void who(){// определение who применительно к second_d

cout << "Second derivation\n";

}

};

int main()

{

Base base_obj;

Base *p;

first_d first_obj;

second_d second_obj;

p = &base_obj;

p->who();

p = &first_obj;

p->who();

p = &second_obj;

p->who();

return 0;

}

Наиболее распространённым способом вызова виртуальной функции служит использование параметра функции.

Пример

/* Здесь ссылка на базовый класс используется для доступа

к виртуальной функции */

#include <iostream>

using namespace std;

class Base {

public:

virtual void who(){// определение виртуальной функции

cout << "Base\n";

}

};

class first_d: public Base {

public:

void who(){// определение who применительно к first_d

cout << "First derivation\n";

}

};

class second_d: public Base {

void who(){// определение who применительно к second_d

cout << "Second derivation\n";

}

};

// использование в качестве параметра ссылки на базовый класс

void show_who(Base &r) {

r.who();

}

int main()

{

Base base_obj;

first_d first_obj;

second_d second_obj;

show_who(base_obj);

show_who(first_obj);

show_who(second_obj);

return 0;

}

Для чего нужны виртуальные функции?

Виртуальные функции в комбинации с производными типами позволяют С++ поддерживать полиморфизм времени исполнения. Этот полиморфизм важен для ООП, поскольку он позволяет переопределять функции базового класса в классах потомках с тем, чтобы иметь их версию применительно к данному конкретному классу. Таким образом, базовый класс определяет общий интерфейс, который имеют все производные от него классы, и вместе с тем полиморфизм позволяет производным классам иметь свои собственные реализации методов. Благодаря этому полиморфизм часто определяют фразой «один интерфейс – множество методов».

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

Пример

#include <iostream>

using namespace std;

class figure {

protected:

double x, y;

public:

void set_dim(double i, double j) {

x = i; y = j;

}

virtual void show_area() {

cout << "No area computation defined ";

cout << "for this class.\n";

}

};

class triangle: public figure {

public:

void show_area() {

cout << "Triangle with height ";

cout << x << " and base " << y;

cout << " has an area of ";

cout << x*0.5*y << ".\n";

}

};

class square: public figure {

public:

void show_area() {

cout << "Square with dimensions ";

cout << x << "x" << y;

cout << " has an area of ";

cout << x*y << ".\n";

}

};

int main()

{

figure *p;

triangle t;

square s;

p = &t;

p->set_dim(10.0, 5.0);

p->show_area();

p = &s;

p->set_dim(10.0, 5.0);

p->show_area();

return 0;

}