Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Книга C++.doc
Скачиваний:
24
Добавлен:
10.11.2019
Размер:
2.48 Mб
Скачать

Наследование (Inheritance). Часть 2.

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

заголовок_функции: имя_базового_класса (список аргументов)

Если параметр имя_базового_класса (список аргументов) пропущен, то вызывается конструктор по умолчанию базового класса.

Чтобы заглянуть внутрь механизма наследования и проверить утверждение приведенное выше, давайте рассмотрим следующий пример:

#include <iostream.h>

class Base

{

public:

Base(){cout<<"Base constructor!\n";}; //конструктор

~Base(){cout<<"Base destructor!\n";}; //деструктор

};

class PublicDerived:public Base

{

public:

PublicDerived(){cout<<"PublicDerived constructor!\n";}; //конструктор

~PublicDerived(){cout<<"PublicDerived destructor!\n";}; //деструктор

};

class PrivateDerived:private Base

{

public:

PrivateDerived(){cout<<"PrivateDerived constructor!\n";}; //конструктор

~PrivateDerived(){cout<<"PrivateDerived destructor!\n";}; //деструктор

};

void main()

{

Base aBase1; //экземпляр базового класса

// PublicDerived aPublicDerived1; //экземпляр public-производного класса

// PrivateDerived aPrivateDerived1; //экземпляр private-производного класса

}

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

Base constructor!

Base destructor!

Теперь, попробуйте разкоментировать объявления объекта aPublicDerived1 в функции main. Результатом работы программы будет вывод на экран сообщений:

Base constructor!

Base constructor!

PublicDerived constructor!

PublicDerived destructor!

Base destructor!

Base destructor!

И, наконец, разкоментируйте объявления объекта aPrivateDerived1 в функции main. Результатом работы программы будет вывод на экран сообщений:

Base constructor!

Base constructor!

PublicDerived constructor!

Base constructor!

PrivateDerived constructor!

PrivateDerived destructor!

Base destructor!

PublicDerived destructor!

Base destructor!

Base destructor!

Таким образом, мы с Вами выяснили следующий факт: при создании объекта производного класса (например, PublicDerived) вызывается конструктор родительского класса. При уничтожении объекта производного класса, вызывается деструктор родительского класса. Причем, последовательность вызовов конструкторов при создании объекта следующая: конструктор родительского класса, конструктор производного класса. При уничтожении - деструктор производного класса, деструктор родительского класса.

Следующий пример иллюстрирует очередность вызовов конструкторов и деструкторов для экземпляра класса PD, который наследуется от класса PublicDerived. Класс PublicDerived, в свою очередь, наследуется от класса Base.

#include <iostream.h>

class Base //родительский класс

{

public:

Base(){cout<<"Base constructor!\n";};

~Base(){cout<<"Base destructor!\n";};

void Func() //public-функция в родительском классе

{cout<<"------Hello from Base\n";}

};

class PublicDerived:public Base //объявление производного public-класса

{

public:

PublicDerived(){cout<<"PublicDerived constructor!\n";};

~PublicDerived(){cout<<"PublicDerived destructor!\n";};

void Func() //public-функция в наследуемом классе

{

Base::Func(); //вызвали функцию родительского класса

cout<<"------Hello from PublicDerived\n"; //добавили собственные изменения

}

};

class PD:public PublicDerived //объявление производного public-класса

{

public:

PD(){cout<<"PD constructor!\n";};

~PD(){cout<<"PD destructor!\n";};

};

void main()

{

PD aPD1; //экземпляр производного класса

aPD1.Func();//вызов метода родителя (PublicDerived)

}

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

Base constructor!

PublicDerived constructor!

PD constructor!

------Hello from Base

------Hello from PublicDerived

PD destructor!

PublicDerived destructor!

Base destructor!

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

#include <iostream.h>

class Base //снова содаем базовый класс

{

public:

Base() //конструктор по умолчанию

{cout<<"Base constructor!\n";};

Base(int a) //конструктор - его то и будем вызвать из производного класса

{cout<<"--Base constructor2222!\n";};

~Base(){cout<<"Base destructor!\n";};

};

class PublicDerived:public Base //объявим производный public-класс

{

public:

PublicDerived()

{cout<<"PublicDerived constructor!\n";};

PublicDerived(int a):Base(a)

{cout<<"--PublicDerived constructor222!\n";};

~PublicDerived(){cout<<"PublicDerived destructor!\n";};

};

void main()

{

PublicDerived aPD1(10); //экземпляр производного класса

}

Результат работы программы будет таким:

--Base constructor2222!

--PublicDerived constructor222!

PublicDerived destructor!

Base destructor!

Попробуйте изменить строку

PublicDerived aPD1(10); //экземпляр производного класса

на

PublicDerived aPD1; //экземпляр производного класса

Результат работы программы будет другим, так как в производном классе произойдет вызов конструктора по умолчанию родительского класса.