
Лекции по ППВиС (17 шт, ppt) Романов ВИ 2011 1ый семестр / Л7_Множественное наследие
.ppt
Тест с отчетом 1 |
1 |
|
|
||
1) Скомпилируется ли следующий код: |
class Clazz |
(да/нет |
|
{ }; |
) |
2) Перечислите все правильные способы объявления локальной константы в блоке кода.
3) Что будет выведено на экран в результате компиляции и выполнения следующего кода?
(1)Ошибка
компиляции
(2)1711
(3)2323
(4)Ошибка
выполнения (укажите номер)
(5) 2424
(1) |
#const size = |
(перечислит |
|
5; |
define const |
е номера) |
|
(2) |
|
|
|
size 5 |
|
|
|
(3) |
const int size; |
|
|
(4) |
#include <iostream> |
|
|
5; |
int a = 23; |
|
|
|
|
|
|
|
int main(int argc, char * argv[]) |
||
|
{ |
|
|
|
++--++--++--++--++--++-- |
||
|
a; |
|
--a; |
|
++a; std::cout << a; |
||
|
++--++--++--++--++--++-- |
||
|
a; |
|
--a; |
|
++a; std::cout << a; |
++--++--++--++--++--++--
a;

2
Наследование
Варианты…
Одиночное |
Множественн |
наследовани |
ое |
е |
наследовани |
|
е |
При множественном наследовании объекты производных классов могут использовать данные и методы нескольких классов, а также в свою очередь быть базовыми классами для
других.

3
Множественное наследование - определение
class D: атрибут_наследования base1, …, атрибут_наследования baseN
{
. . .
};
Атрибуты наследования и их смысл тот же, что и при одиночном наследовании.
Данная последовательность базовых классов определяет порядок вызова конструкторов базовых классов.
При создании экземпляра объекта производного класса в первую очередь вызовется конструктор базового класса, имя которого определено первым в списке наследуемых классов. Далее – по порядку. Последним вызовется конструктор производного класса.
При уничтожении объекта производного класса деструкторы вызываются в обратном порядке вызовам конструкторов.

4
Аргументы конструкторов
Как и для одиночного наследования, если конструктор или конструкторы базового класса содержат как минимум один аргумент, то производный класс также должен содержать конструктор.
Если конструктор базового класса имеет аргументы без умолчания, то их надо передать через конструктор производного класса.
При описании конструктора производного класса задаются те конструкторы базовых классов, которые имеют аргументы.
Если конструктор базового класса не имеет аргументов, или все аргументы такого конструктора используются по умолчанию, то имя такого конструктора можно на задавать в описании производного
класса.
base1 (список аргументов), …, baseN (список аргументов)
{
. . .
}
Список конструкторов базовых классов не влияет на порядок их вызова. Он определяется только списком имен базовых классов в начале определения производного класса!

5
Виртуальные базовые классы
В С++ запрещено непосредственно передавать базовый класс в производный более одного раза, т.е. имя класса в списке базовых классов повторяться не может.
class A { . . . };
class B: public A, protected A { . . . }; //Нельзя!
Однако могут возникать ситуации, когда один производный класс косвенно может наследовать один и тот же базовый класс через другие базовые классы.
Например: |
class B: public A |
class C: public A , public B |
class A |
||
{ |
{ |
{ |
public: |
. . . |
. . . |
int n; |
}; |
}; |
. . . |
|
|
}; |
|
|

6
Виртуальные базовые классы - пример
Объект класса A
int n;
Объект класса B
Объект класса
int n;
Объект класса C
Объект класса
int n;
Объект класса B
Объект класса
int n;
По примеру получается такая структура объектов
Ситуация
неоднозначности: С obj;
obj.n=0; // Ошибка

7
Виртуальные базовые классы - пример
Такое наследование вполне возможно и компилятор не выдаст сообщение об ошибке, а только предупредит, что наследуемый класс А также находится в наследуемом классе B.
В данном примере ошибка возникнет на стадии компиляции. Компилятор не различит, какую именно
переменную с именем n базового класса необходимо изменить: или переменную , которая непосредственно является компонентой класса A, или переменную, которая доступна из наследуемого класса B?
Решить такую проблему в С++ можно путем
использования виртуальных базовых классов.

8
Виртуальные базовые классы - пример
Если один базовый класс косвенно наследуется в одном производном классе и наследуется с атрибутом virtual, то в экземпляр производного класса будет помещена только одна копия базового класса.
Базовый класс объявляется как виртуальный только при наследовании – в списках базовых классов
с указанием спецификации virtual.
class A { . . . };
class B: virtual public A { . . . }; class C: virtual public A, public B
{ . . . };
Если базовый класс наследуется производным как виртуальный, то его компоненты все равно доступны в производном классе.
Отличие между обычным и виртуальным наследованием
заключается в том, что когда класс наследует базовый более одного раза, то он будет содержать только одно вхождение базового класса.

9
Множественное наследование на примере (1)
#include <iostream> using namespace std;
class A { public:
int a;
A(int a) {this->a =a; cout << " Constructor A\n"; } ~A() {cout << " Destructor A\n"; }
void print() { cout << "a = " << a << endl; }
};
class B { public:
int b;
B(int b) {this->b =b; cout << " Constructor B\n"; } ~B() {cout << " Destructor B\n"; }
void print() { cout << "b = " << b << endl; }
};

10
Множественное наследование на примере (2)
class C : virtual public A{ public:
int c;
C(int c): A(c) {this->c =c; cout << " Constructor C\n"; } ~C() {cout << " Destructor C\n"; }
void print() { cout << "c = " << c << endl; } };
class D : public B, virtual public C, virtual public A{ public:
int d;
D(int d): A(d+1), B(d+2), C(d+3) {this->d =d; cout << " Constructor D\n"; }
~D() {cout << " Destructor D\n"; } void print()
{
cout << "d = " << d << endl; A::print(); B::print(); C::print();
}
};