Заглавная страница Избранные статьи Случайная статья Познавательные статьи Новые добавления Обратная связь КАТЕГОРИИ: АрхеологияБиология Генетика География Информатика История Логика Маркетинг Математика Менеджмент Механика Педагогика Религия Социология Технологии Физика Философия Финансы Химия Экология ТОП 10 на сайте Приготовление дезинфицирующих растворов различной концентрацииТехника нижней прямой подачи мяча. Франко-прусская война (причины и последствия) Организация работы процедурного кабинета Смысловое и механическое запоминание, их место и роль в усвоении знаний Коммуникативные барьеры и пути их преодоления Обработка изделий медицинского назначения многократного применения Образцы текста публицистического стиля Четыре типа изменения баланса Задачи с ответами для Всероссийской олимпиады по праву Мы поможем в написании ваших работ! ЗНАЕТЕ ЛИ ВЫ?
Влияние общества на человека
Приготовление дезинфицирующих растворов различной концентрации Практические работы по географии для 6 класса Организация работы процедурного кабинета Изменения в неживой природе осенью Уборка процедурного кабинета Сольфеджио. Все правила по сольфеджио Балочные системы. Определение реакций опор и моментов защемления |
Конструкторы порожденного класса
Если объявляется объект порожденного класса, то за инициализацию базовой части объектов должен отвечать конструктор порожденного класса. Поэтому конструктор класса 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; просмотров: 38; Нарушение авторского права страницы; Мы поможем в написании вашей работы! infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 18.227.0.192 (0.007 с.) |