Материал: 3574

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам

Поэтому данные всегда целесообразно объявлять в разделе private —

закрытом разделе класса. В редких случаях их можно помещать в protected

— защищенном разделе класса, чтобы возможные потомки данного класса имели к ним доступ.

Как правило, делайте данные-элементы класса защищенными,

снабжая их при необходимости открытыми функциями чтения и записи.

Функции записи позволят вам проверять записываемые данные и обеспечивать тем самым непротиворечивость данных. А функции чтения позволят вам не переписывать программу, доже если вы решили изменить что-то в типе, способах хранения и размещения данных в классе,

Приведем пример. Пусть класс имеет следующее объявление:

Class MyClass

{

public:

void SetA(int); // функция записи int GetA(void); // функция чтения private: int FA;

double В, C; };

Реализация функций записи и чтения может иметь вид: void MyClass::SetA(int Value)

{

if(...) // проверка корректности данных

FA = Value;

}

int MyClass::GetA(void) {return FA;}

В данном случае функция чтения просто возвращает значение поля,

но в более сложных классах может потребоваться какая-то предварительная обработка данных. Обратите внимание, что все описания

функций-элементов содержат ссылку на класс с помощью операции разрешения области действия (::).

В приведенном примере объявление класса содержит только прототипы функций, а их реализация вынесена из описания класса. Для простых функций реализация может быть размещена непосредственно в объявлении класса. Например:

class MyClass

{

public: MyClass(int = 0);

void SetA(int Value) {FA = Value;}; // функция записи int GetA(void) {return FA;}; // функция чтения private: int FA; double В, C;

};

Функции, описание которых содержится непосредственно в объявлении класса, в действительности являются встраиваемыми функциями inline.

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

Если уж вы хотите реализовать встраиваемые функции, то лучше поместить в объявлении класса их прототип со спецификатором inline:

inline void SetA{int}; // функция записи

и отдельно дать реализацию функции. При этом в реализации спецификатор inline не указывается.

Объявления классов следует размещать в заголовочном файле модуля, а реализацию функций-элементов в отдельном файле реализации.

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

организация программы обеспечивает независимость всех модулей,

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

Функции-элементы класса имеют доступ к любым другим функциям-элементам и к любым данным-элементам, как открытым, так и закрытым. Клиенты класса (какие-то внешние функции, работающие с объектами данного класса) имеют доступ только к открытым функциям-

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

ответствующую функцию как друга класса с помощью спецификации friend. Например, если в объявление класса включить оператор:

friend void IncFA(MyClass *);

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

void IncFA(MyClass *Р) {P->FA++;}

Дружественными могут быть не только функции, но и целые классы.

Например, вы можете поместить в объявление своего класса оператор: friend Class1;

и все функции-элементы класса Class1 получат доступ к закрытым элементам вашего класса.

Иногда программист может захотеть создать объект вашего класса как константный с помощью спецификатора const. Например:

const Class1 MCI (3);

Если при этом ваш класс содержит не только функции чтения, но и записи данных, то реакция на такой оператор, введенный пользователем,

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

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

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

Например, вы можете включить в объявление класса оператор: int GetA(void) const;

а реализацию этой функции оформить как: int MyClass::GetA(void) const {return FA;}

Тогда неприятные замечания компилятора о константных объектах исчезнут.

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

3.Лабораторные задания.

1.Определить пользовательский класс в соответствии с вариантом задания.

2.Определить в классе следующие конструкторы: без параметров, с параметрами, копирования.

3.Определить в классе деструктор.

4.Определить в классе компоненты-функции для просмотра и установки полей данных.

5.Определить указатель на компоненту-функцию.

6.Определить указатель на экземпляр класса.

7.Написать демонстрационную программу, в которой создаются и разрушаются объекты пользовательского класса и каждый вызов

конструктора и деструктора сопровождается выдачей соответствующего сообщения (какой объект какой конструктор или деструктор вызвал).

8. Показать в программе использование указателя на объект и указателя на компоненту-функцию.

Варианты:

Описания членов - данных пользовательских классов

1.СТУДЕНТ имя – char*

курс – int

пол – int(bool)

2.СЛУЖАЩИЙ имя – char*

возраст – int рабочий стаж – int

3.КАДРЫ

имя – char*

номер цеха – int разряд – int

4.ИЗДЕЛИЕ имя – char* шифр – char*

количество – int

5.БИБЛИОТЕКА имя – char*

автор – char* стоимость – float

6.ЭКЗАМЕН

имя студента – char* дата – int

оценка – int

7.АДРЕС имя – char*

улица – char* номер дома – int

8.ТОВАР

имя – char*

количество – int стоимость – float 9. КВИТАНЦИЯ номер – int

дата – int