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

Закрытый или защищенный

Возможно, вы заметили, что в строках 24 и 45 листинга 11.1 используется новое ключевое слово protected. До сих пор данные класса определялись с ключевым словом private. Но члены класса, объявленные как private, недоступны для наследования. Конечно, можно было в предыдущем листинге определить переменные-члены itsAge и itsWeight как public, но это нежелательно, поскольку прямой доступ к этим переменным получили бы все другие классы программы.

Нашу цель можно сформулировать следующим образом: сделать переменную-член видимой для этого класса и для всех классов, произведенных от него. Именно таковыми являются защищенные данные, определяемые ключевым словом protected. Защищенные данные доступны для всех произведенных классов, но недоступны для всех внешних классов.

Обобщим: существует три спецификатора доступа — public, protected и private. Если в функцию передаются объекты класса, то она может использовать данные всех переменных-членов и функций-членов, объявленных со спецификатором public. Функция-член класса, кроме того, может использовать все закрытые данные этого класса (объявленные как private) и защищенные данные любого другого класса, произведенного от этого класса (объявленные как protected).

Так, в нашем примере функция Dog::WagTail() может использовать значение закрытой переменной itsBreed и все переменные класса Mammal, объявленные как public и protected.

Даже если бы класс Dog был произведен не от класса Mammal непосредственно, а от какого-нибудь промежуточного класса (например, DomesticAnimals), все равно из класса Dog сохранился бы доступ к защищенным данным класса Mammal, правда только в том случае, если класс Dog и все промежуточные классы объявлялись как public. Наследование класса с ключевым словом private будет рассматриваться на занятии 15.

В листинге 11.2 показано создание объекта в классе Dog с доступом ко всем данным и функциям этого типа.

Листинг 11.2. Использование унаследованных объектов  

1: // Листинг 11.2. Использование унаследованных объектов

2:

3: #include <iostream.h>

4: enum BREED < GOLDEN, CAIRN, DANDIE, SHETLAMD, DOBERMAN, LAB };

5:

6: class Mammal

7: {

8:    public:

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

10:      Mammal():itsAge(2), itsWeight(5){ }

11:  ~Mammal(){ }

12:

13:      //Методы доступа

14:      int GetAge()const { return itsAge; }

15:      void SetAge(int age) { itsAge = age; }

16:      int GetWeight() const { return itsWeight; }

17:      void SetWeight(int weight) { itsWeight = weight; }

18:

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

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

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

22:

23:

24:   protected:

25:      int itsAge;

26:      int itsWeight;

27: };

28:

29: class Dog : public Mammal

30: {

31:    public:

32:

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

34:       Dog():itsBreed(GOLDEN){ }

35:       ~Dog(){ }

36:

37:       // Методы доступа

38:       BREED GetBreed() const { return itsBreed; }

39:       void SetBreed(BREED breed) { itsBreed = breed; }

40:

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

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

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

44:

45:    private:

46:       BREED itsBreed;

47: };

48:

49: int main()

50: {

51:    Dog fido;

52:    fido.Speak();

53:    fido.WagTail();

54:    cout << "Fido is " << fido.GetAge() << " years old\n";

55:    return 0;

56: }

Результат:

Mammal sound!

Tail wagging...

Fido is 2 years old

Анализ: В строках 6-27 объявляется класс Mammal (для краткости тела функций вставлены по месту их вызовов). В строках 29—47 из класса Mammal производится класс Dog. В результате объекту Fido этого класса доступны как функция производного класса WagTail(), так и функции базового класса Speak() и Sleep().