Конструкторы порожденного класса 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Конструкторы порожденного класса



 

Если объявляется объект порожденного класса, то за инициализацию базовой части объектов должен отвечать конструктор порожденного класса. Поэтому конструктор класса B имеет специальную форму (на примере наших классов A и B):

 

список инициализации

                 

B:: B(int  a, int  b, int  c): A(a, b, c) 

{ d3 = d4 = b;}

 

В список инициализации может быть включена инициализация член-данных порожденного класса.

Например,

 

B:: B(int  a, int  b, int  c): A(a, b, c), d3(b), d4(b)  { }      (1)

 

Заметим, что для нашего примера инициализация может выглядеть и другими способами:

 

B:: B(int  a, int  b, int  c, int  d, int  r): A(a, b, c), d3(d), d4(r) { }  (2)

 

Пример использования конструкторов:

 

void  main()

{A  x, y(3, 6, 7); // конструкторы без аргументов и с аргументами класса A

B  z(1, 2, 3, 4, 5); // конструктор (2): 1, 2, 3 инициализируют базовую часть объекта z (d1, d2, d3),

// а 4, 5 – порожденную (d3, d4)

}

 

Если в базовом классе задан конструктор по умолчанию, то в списке инициализации конструктора порожденного класса он может отсутствовать. То есть конструктор класса B может иметь вид:

 

B:: B(int a, int b): A() {d3 = a; d4 = b;}

 

или

 

B:: B(int a, int b) {d3 = a; d4 = b;}

 

Однако и в первом и во втором случае конструктор по умолчанию класса A работать будет. При инициализации объектов порожденного класса сначала работают конструкторы базового, а затем порожденных классов и так по всей иерархии порождения. Этот факт позволяет при инициализации член-данных порожденного класса использовать уже проинициализированные член-данные базового класса. То есть конструктор класса B может быть задан таким необычным образом:

 

B:: B(int  a, int  b, int  c): A(a, b, b)    // A:: d1 = a; A:: d2 = b; A:: d3 = b

{d3 = d2 * A:: d3; d4 = c;}

 

Деструкторы, наоборот, сначала разрушают член-данные порожденного класса, затем базового.

3. Стандартные преобразования при наследовании

 

Пусть заданы объекты порожденного класса и базового

 

A x; B  y(1, 2, 3, 4, 5);    // конструктор (2)

 

Что будет верным:

 

x = y;

 

или

 

y = x;?

Ответ:    x = y;

При наследовании действуют по умолчанию такие правила преобразования:

1)  объект порожденного класса преобразуется к объекту базового (путем отбрасывания порожденных член-данных). В обратную сторону преобразование не определено (и может быть задано только пользователем, как правило, конструктором вида B(A&)).

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

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

 

 

Итак,

 

void  main()

{A  x, *pA; // Для x работает конструктор по умолчанию

B  y(1, 2, 3, 4, 5), *pB; // Для y работает конструктор (2)

 x = y;   // Верно: x.d1 = y.d1 = 1; x.d2 = y.d2 = 2; x.d3 = y.A:: d3 = 3;

y = x;   // Неверно: что записать в y.d3, y.d4 из x?

// как из маленького пальто нельзя сшить большое, а наоборот – можно (см. рисунок)

 pA = &y; // верно: преобразование B* –> A* определено по умолчанию

pA –> Print(); //функция A::Print() выведет базовую часть объекта y

 pB = &x;          // неверно, преобразование A* –> B* неопределенно по умолчанию

pB = (A *)pA;   // операция явного преобразования A* –> B*

}

Замечание. Если в классах A и B определяются конструкторы копирования

 

A(A &) и B(B &),

 

то последний имеет вид

 

B:: B(B &b1): A(b1) {...},

 

в котором в списке инициализации базовая часть объекта b1 передается конструктору копироваия класса A. При этом используется стандартное преобразование объектов порожденного класса к базовому.

 



Поделиться:


Последнее изменение этой страницы: 2021-12-07; просмотров: 37; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 52.14.84.29 (0.006 с.)