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




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

1 Зачем используются конструкторы и деструкторы?

2 Какое имя имеет конструктор и деструктор?

3 Сколько конструкторов и деструкторов может быть в классе?

4 Можно ли выполнить инициализацию данных-членов без конструктора?

5 Назовите отличия конструкторов и деструкторов от других функций

6 Можно ли явно вызвать конструктор и деструктор?

7 Можно ли передать параметры в конструкторы, использовать параметры по умолчанию?

8 Как определить вызываемый конструктор, если их несколько?

9 Что такое конструктор по умолчанию, конструктор копии?

10 Приведите синтаксис объявления, определения и использования конструкторов, какие альтернативные варианты допустимы?

11 Объясните приведенные примеры.

12 Для чего необходимы оператора new и delete.

13 Когда вызываются деструкторы для локальных и глобальных переменных

14 Как происходит вызов деструкторов при выходе из программы, при вызове функций ехit(), abord()?

Лабораторная работа №22

Использование наследования для создания иерархии классов

(2 часа)

Цель работы: получить навыки в использовании наследования для создания производных классов при простом наследовании.

Теоретические сведения

При объявлении производного класса D перечисляются базовые классы В1, В2... в разделяемом запятой "базовом_списке". Cинтаксис объявления производного класса.

сlass <Имя_класса_D>:<Базовые_классы> {<список_элементов>};

При объявлении класса D перед классами в базовом списке вы можете задать спецификатор доступа public, или private, или protected.

class D: public B1, private B2,... {

...

};

Эти спецификаторы не изменяют доступа к элементам с точки зрения базового класса, но могут изменить доступ к элементам базовых классов из производных классов.

Если D представляет собой объявление класса (class), то по умолчанию используется private, а если D - объявление структуры (struct), то public.

Класс D наследует все элементы базовых классов. (Переопределенные элементы базовых классов наследуются и при необходимости доступ к ним возможен при помощи переопределений области действия). D может использовать элементы базовых классов только с атрибутами public и protected.

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

1 Если базовый класс указанв списке как public:

- элементы public базового класса становятся элементами public производного класса.

- элементы protected базового класса становятся элементами protected производного класса.

- элементы private базового класса остаются private для производного класса.

2 2. Если базовый класс protected:

- элементы базового класса общедоступные (public) и защищенные (protected) становятся защищенными (protected) элементами производного класса.

- элементы private базового класса остаются для произвольного класса private.

3 3. Если базовый класс private:

- общедоступные (public) и защищенные (protected) члены базового класса становятся частными (private) элементами производного класса.

- элементы private базового класса остаются для производного класса private.

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

class X: A { // класс X является производным от класса А (простое

// наследование), причём по умолчанию спецификатор - private A

}

class Y: B, public C { // класс Y является производным (множественное

// наследование) от B и C. По умолчанию - private B, спецификатор для С- public

}

struct S: D { // struct S - производная от D, по умолчанию для структур

// struct - public D

..,

}

struct T: private D, E { // struct T является производной (множественное

// наследование) от D и E. Спецификатор для D – private D. По умолчанию,

// E - public E

}

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

class B {// базовый класс int a; //по умолчанию // private public: int b, c; int Bfunc(void); }; class X: private B { // теперь члены базового класса // В::a, b, c и B func() - стали private в классе //наследнике Х.Переменная ав Х недоступна int d; // по умолчанию private public: B::c; // переменная cбыла private; теперь она public: int e; int Xfunc(void); };

int Efunc(X& x); // внешняя по отношению к классам В и Х, требует

// ссылку на объект х класса Х.

Функция Efunc() может использовать только имена членов класса Х с атрибутом public, например х.c, х.e и х.Xfunc.

Функция Xfunc() в X является функцией-членом, поэтому она имеет доступ:

1 к собственным private и public элементам: d, e и Xfunc().

2 к старшим private элементам базового класса В: b и Bfunc().

3 Однако, Xfunc не имеет доступа к private относительно B элементу a.

4 к переменной с класса В явно заданной public c помощью (::) – В::с.

Конструкторы базового класса должны объявляться с атрибутами public или protected. Причём: конструкторы производных классов обязательно вызывают конструкторы базовых классов.

Примеры:

class base1 { int x; public: base1(int i) { x = i; } }; class base2 { int x; public: base2(int i): x(i) {} }; class top: public base1, public base2 { int a, b; public: top(int i, int j): base(i*5), base2(j+i), a(i) { b = j;} };

В случае такой иерархии классов объявление top one(1, 2) приведет к инициализации base 1::х значением 5, а base2::х значением 3. Методы инициализации могут комбинироваться друг с другом (чередоваться).

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

Class X

{

int a, b;

public:

X(int i, j): a(i), b(a+j) {}

};

Объявление X xobj (2.1) приведет к присваиванию xobj::a числа 2 и xobj::b числа 3.

Конструкторы базовых классов вызываются перед конструированием любых элементов производных классов. Значения данных-членов производного класса не могут изменяться и затем влиять на создание базового класса.

class base { int x; public: base(int i): x(i) {} };   class derived: base { int a; public: derived(int i): a(i*10), base(a) {} //нельзя, т.к. // конструктору base будет передано неинициализированное a }

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



Поделиться:




Поиск по сайту

©2015-2024 poisk-ru.ru
Все права принадлежать их авторам. Данный сайт не претендует на авторства, а предоставляет бесплатное использование.
Дата создания страницы: 2022-09-06 Нарушение авторских прав и Нарушение персональных данных


Поиск по сайту: