Читаем Освой самостоятельно С++ за 21 день. полностью

Например, в объявлении класса Cat указывается, что программа-клиент может инициализировать любой возраст объекта этого класса с помощью функции доступа SetAge и возвратить это значение с помощью функции доступа GetAge. При этом гарантируется, что каждый объект класса Cat сможет вывести сообщение Meow на экран с помощью функции-члена Meow. Обратите внимание, что в открытом интерфейсе класса ничего не говорится о закрытой переменной-члене itsAge, которая используется при выполнении класса и не должна интересовать клиентов. Значение возраста можно возвратить из объекта с помощью GetAge и установить с помощью SetAge, но сама переменная itsAge, в которой хранится это значение, скрыта от клиентов.

Если объявить функцию GetAge со спецификатором const, а именно этого требуют правила хорошего тона программирования, в соглашение также будет внесен пункт о том, что функцию GetAge нельзя использовать для изменения значений объекта класса Cat.

В языке C++ осуществляется строгий контроль за типами данных, поэтому подобное соглашение между классом и клиентами будет законом для компилятора, который сгенерирует ошибку компиляции в случае нарушения этого соглашения. В листинге 6.5 показан пример программы, которую не удастся скомпилировать из-за нарушения этих самых соглашений.


Предупреждение:Листинг 6.5 не компилируется!


Листинг 6.5. Пример нарушения соглашений интерфейса

1: // Пример ошибки компиляции, связанной

2: // с нарушениями соглашений интерфейса класса

3:

4: #include // для объекта cout

5:

6: class Cat

7: {

8: public:

9:    Cat(int initialAge);

10:    ~Cat;

11:    int GetAge const; // метод доступа const

12:    void SetAge (int age);

13:    void Meow;

14: private:

15:    int itsAge;

16: };

17:

18: // конструктор класса Cat

19: Cat::Cat(int initialAge)

20: {

21:    itsAge = initialAge;

22:    cout << "Cat constructor\n";

23: }

24: Cat::~Cat // деструктор, который не выполняет никаких действий

25: {

26:    cout << "Cat destructor\n";

27: }

28: // функция GetAge объявлена как const,

29: // но мы нарушаем это условие!

30: int Cat::GetAge const

31: {

32:    return (itsAge++); // это нарушение соглашения интерфейса!

33: }

34:

35: // определение функции SetAge как открытого

36: // метода доступа к данным класса

37:

38: void Cat::SetAge(int age)

39: {

40:    // присваиваем переменной-члену itsAge

41:    // значение переданного парйметра age

42:    itsAge = age;

43: }

44:

45: // Определение метода Meow

46: // возвращает void

47: // параметров нет

48: // используется для вывода на экран текста "Meow"

49: void Cat::Meow

50: {

51:    cout << "Meow.\n";

52: }

53:

54: // демонстрирует различные нарушения

55: // интерфейса, что приводит к ошибкам компиляции

56: int main

57: {

58:    Cat Frisky; // не соответствует обьявлению

59:    Frisky.Meow;

60:    Frisky.Bark; // Нет, кошки не лают.

61:    Frisky.itsAge = 7; // переменная itsAge закрыта

62:    return 0;

63: }


Анализ: Как упоминалось выше, эта программа не компилируется. Поэтому и отсутствуют результаты ее работы.

Эту программу было забавно писать, поскольку в нее специально закладывались ошибки.

В строке 11 GetAgeобъявляется как функция доступа к данным-членам класса без права их изменения, на что указывает спецификатор const. Однако в теле функции GetAge, а именно в строке 32, выполняется приращение переменной-члена itsAge. А поскольку этот метод объявлен как const, он не имеет права изменять значение переменной itsAge. Следовательно, во время компиляции программы на этой строке будет зафиксирована ошибка.

В строке 13 объявляется метод Meow, в этот раз без использования ключевого слова const. И хотя такое упущение не является ошибкой, это далеко не лучший стиль программирования. Если учесть, что этот метод не должен изменять значения переменных-членов класса Cat, то его следовало бы определить со спецификатором const.

В строке 58 показано определение объекта класса Cat с именем Frisky. В этом варианте программы класс Cat имеет конструктор, который принимает в качестве параметра целочисленное значение. Это означает обязательность передачи параметра заданного типа. Поскольку в строке 58 никакой параметр не передается, компилятор зафиксирует ошибку.


Примечание:Если в классе объявляется какой-либо конструктор, компилятор в этом случае не станет предлагать со своей стороны никакого другого конструктора даже если определение объекта по форме не будет coответствовать объявленному конструктору. В подобных случаях компилятор покажет сообщение об ошибке.


В строке 60 вызывается метод Bark. Этот метод вообще не был объявлен, следовательно, ни о каком его использовании и речи быть не может.

Перейти на страницу:

Похожие книги

Сущность технологии СОМ. Библиотека программиста
Сущность технологии СОМ. Библиотека программиста

В этой книге СОМ исследуется с точки зрения разработчика C++. Написанная ведущим специалистом по модели компонентных объектов СОМ, она раскрывает сущность СОМ, помогая разработчикам правильно понять не только методы модели программирования СОМ, но и ее основу. Понимание мотивов создания СОМ и ее аспектов, касающихся распределенных систем, чрезвычайно важно для тех разработчиков, которые желают пойти дальше простейших приложений СОМ и стать по-настоящему эффективными СОМ-программистами. Показывая, почему СОМ для распределенных систем (Distributed СОМ) работает именно так, а не иначе, Дон Бокс дает вам возможность применять эту модель творчески и эффективно для ежедневных задач программирования.

Дональд Бокс

Программирование, программы, базы данных / Программирование / Книги по IT