Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Либерти Джесс. Освой самостоятельно С++ за 21 день. - royallib.ru.rtf
Скачиваний:
1
Добавлен:
01.07.2025
Размер:
2.55 Mб
Скачать

Замещение функций

Объект класса Dog имеет доступ ко всем функциям-членам класса Mammal, а также к любой функции-члену, чье объявление добавлено в класс Dog, например к функции WagTaill(). Но кроме этого, базовые функции могут быть замещены в производном классе. Под замещением базовой функции понимают изменение ее выполнения в производном классе для объектов, созданных в этом классе.

Если в производном классе создается функция с таким же возвратом и сигнатурой как и в базовом классе, но выполняемая особым образом, то имеет место замещение метода.

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

В листинге 11.5 показано замещение в классе Dog функции Speak(), объявленной в классе Mammal. Для экономии места знакомые по предыдущим листингам объявления методов доступа в этом примере были опущены.

Листинг 11.5. Замещение метода базового класса в производном классе

1: //Листинг 11.5. Замещение метода базового класса в производном классе

2:

3: #include <iostream.h>

4: enum BREED { GOLDEN, CAIRN, DANDIE, SHETLAND, DOBERMAN, LAB };

5:

6: class Mammal

7: {

8:    public:

9:       // Конструкторы

10:      Mammal() { cout << "Mammal constructor...\n"; }

11:      ~Mammal() { cout << "Mammal destructor...\n"; }

12:

13:      //Другие методы

14:      void Speak()const { cout << "Mammal sound!\n"; }

15:      void Sleep()const { cout << "shhh. I'm sleeping.\n"; }

16:

17:

18:   protected:

19:  int itsAge;

20:      int itsWeight;

21: };

22:

23: class Dog : public Mammal

24: {

25:    public:

26:

27:       // Конструкторы

28:       Dog(){ cout << "Dog constructor...\n"; }

29:       ~Dog(){ cout << "Dog destructor...\n"; }

30:

31:       // Другие методы

32:       void WagTail() const { cout << "Tail wagging...\n"; }

33:       void BegForFood() const { cout << "Begging for food...\n"; }

34:       void Speak() const { cout << "Woof!\n"; }

35:

36:    private:

37:       BREED itsBreed;

38: };

39:

40: int main()

41: {

42:    Mammal bigAnimal;

43:    Dog fido;

44:    bigAnimal.Speak();

45:    fido.Speak();

46:    return 0;

47: }

Результат:

Mammal constructor...

Mammal constructor...

Dog constructor...

Mammal sound!

Woof!

Dog destructor...

Mammal destructor...

Mammal destructor...

Анализ: В строке 34 в классе Dog происходит замещение метода базового класса

Speak(), в результате чего в случае вызова этой функции объектом класса Dog на экран выводится Woof!. В строке 42 создается объект bigAnimal класса Mammal, в результате чего вызывается конструктор класса Mammal и на экране появляется первая строка. В строке 43 создается объект Fido класса Dog, что сопровождается последовательным вызовом сначала конструктора класса Mammal, а затем конструктора класса Dog. Соответственно на экран выводится еще две строки.

В строке 44 объект класса Mammal вызывает метод Speak(), а в строке 45 уже объект класса Dog обращается к этому методу. На экран при этом выводится разная информация, так как метод Speak() в классе Dog замещен. Наконец выполнение программы выходит за область видимости объектов и для их удаления вызываются соответствующие пары деструкторов.

Перегрузка или замещение

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