Например, в объявлении класса Cat указывается, что программа-клиент может инициализировать любой возраст объекта этого класса с помощью функции доступа SetAge и возвратить это значение с помощью функции доступа GetAge. При этом гарантируется, что каждый объект класса Cat сможет вывести сообщение Meow на экран с помощью функции-члена Meow. Обратите внимание, что в открытом интерфейсе класса ничего не говорится о закрытой переменной-члене itsAge, которая используется при выполнении класса и не должна интересовать клиентов. Значение возраста можно возвратить из объекта с помощью GetAge и установить с помощью SetAge, но сама переменная itsAge, в которой хранится это значение, скрыта от клиентов.
Если объявить функцию GetAge со спецификатором const, а именно этого требуют правила хорошего тона программирования, в соглашение также будет внесен пункт о том, что функцию GetAge нельзя использовать для изменения значений объекта класса Cat.
В языке C++ осуществляется строгий контроль за типами данных, поэтому подобное соглашение между классом и клиентами будет законом для компилятора, который сгенерирует ошибку компиляции в случае нарушения этого соглашения. В листинге 6.5 показан пример программы, которую не удастся скомпилировать из-за нарушения этих самых соглашений.
Предупреждение:
Листинг 6.5. Пример нарушения соглашений интерфейса
1: // Пример ошибки компиляции, связанной
2: // с нарушениями соглашений интерфейса класса
3:
4: #include
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 никакой параметр не передается, компилятор зафиксирует ошибку.
Примечание:
В строке 60 вызывается метод Bark. Этот метод вообще не был объявлен, следовательно, ни о каком его использовании и речи быть не может.