Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по С++ глава 3.doc
Скачиваний:
6
Добавлен:
05.11.2018
Размер:
187.9 Кб
Скачать

3.3. Доступ к членам класса

После создания экземпляра класса организуется доступ к переменным-членам и функциям-членам класса. При этом используется синтаксис, подобный применяемому для работы со структурами языка С. Однако при наличии одного только определения класса CRectangle программа не сможет обратится ни к одному из его членов, так как по умолчанию все переменные и функции, принадлежащие классу, определены как закрытые (private) (иногда говорят внутренние, личные или частные). Это означает, что они могут использоваться только внутри функций-членов самого класса. Так, для функции Draw разрешен доступ к переменным-членам Top, Left, Right и Bottom, потому что Draw – функция-член класса. Для других частей программы, таких как функция main, доступ к переменным-членам или вызов функции-члена Draw запрещен.

К счастью, можно использовать спецификатор доступа public, чтобы создать открытый член класса (иногда называемый общедоступным или публичным), доступный для использования всеми функциями программы (как внутри класса, так и за его пределами). Например, в следующем варианте класса Rectangle все члены являются открытыми.

class CRectangle

{

public:

Int Left;

int Top;

Int Right;

Int Bottom;

void Draw (void)

{

Line (Left, Top, Right, Top);

Line (Right, Top, Right, Bottom);

Line (Right, Bottom, Left, Bottom);

Line (Left, Bottom, Left, Top);

}

};

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

Теперь, когда все члены класса CRectangle открыты, доступ к ним, как и доступ к полям структуры в языке С, возможен с использованием оператора "."

CRectangle Rect; // определение объекта CRectangle

Rect.Left= 5; // присваивание значений переменным-членам

Rect.Top = 10; // для указания координат прямоугольника

Rect.Right = 100;

Rect.Bottom = 150;

Rect.Draw (); // создание прямоугольника

С другой стороны, можно создать экземпляр класса оператором new, а затем использовать указатель на экземпляр для доступа к переменным-членам класса, как показано в следующем коде.

CRectangle *PRect = new CRectangle;

PRect->Left = 5;

PRect->Tор = 10;

PRect->Right = 100;

PRect->Bottom =150;

PRect->Draw ();

3.4. Инкапсуляция

Согласно принципам инкапсуляции внутренние структуры данных, используемые в реализации класса, не должны быть доступны пользователю класса непосредственно (преимущества инкапсуляции будут рассмотрены ниже). Однако текущая версия класса CRectangle явно нарушает этот принцип, так как пользователь может непосредственно читать или модифицировать любые переменные-члены.

Для достижения большей инкапсуляции класс CRectangle должен быть определен так, чтобы иметь доступ к функциям-членам (в нашем случае к Draw), но не иметь доступа к внутренним переменным-членам, используемым этими функциями (Left, Top, Right и Bottom).

class CRectangle

{

private:

Int Left;

int Top;

Int Right;

Int Bottom;

public:

void Draw (void)

{

Line (Left, Top, Right, Top);

Line (Right, Top, Right, Bottom);

Line (Right, Bottom, Left, Bottom);

Line (Left, Bottom, Left, Top);

}

};

Спецификатор доступа private делает переменные, определенные позже, закрытыми. Таким образом, они доступны только функциям-членам класса. Подобно спецификатору доступа public, рассмотренному ранее, спецификатор private воздействует на все объявления, стоящие после него, пока не встретится другой спецификатор. Следовательно, такое определение делает переменные Left, Top, Right и Bottom закрытыми, а функцию Draw открытой. Заметим: в действительности не требуется помещать спецификатор private в начале определения класса, потому что члены класса по умолчанию являются закрытыми. Однако включение спецификатора private облегчает чтение программы.

Примечание

Язык C++ предоставляет еще и третий вид доступа – protected. Этот спецификатор будет рассмотрен в гл. 4, поскольку требует понимания термина "наследование".

Следующий код иллюстрирует как корректное, так и некорректное обращение к членам очередного варианта класса CRectangle.

void main()

{

CRectangle Rect; // определение объекта CRectangle

Rect.Left = 5; // ОШИБКА: нет доступа к закрытому члену

Rect.Top =10; // ОШИБКА

Rect.Right =100; // ОШИБКА

Rect.Bottom =150; // ОШИБКА

Rect.Draw (); // допускается (но координаты не определены)

}

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

void SetCoord (int L, int Т, int R, int B)

{

L = _min (_max (0,L), 80);

Т = _min (_max (0,T), 25);

R = _min (_max (0,R), 80);

В = _min (_max (0,B), 25);

R = _max (R,L) ;

В = _max (B,T);

Left = L; Top = T; Right = R; Bottom = B;

}

Эта функция добавляется в раздел public определения класса CRectangle. Поэтому ее можно вызвать из любой функции программы. Обратите внимание: при необходимости, перед присваиванием параметров переменным класса, функция SetCoord организует проверку нахождения параметров в диапазоне корректных значений и следит, чтобы правая координата была больше левой, а нижняя – больше верхней. Макросы _max и _min предоставляются динамической библиотекой языка C++. Для их применения в программу нужно включить файл заголовков Stdlib.h.

Теперь класс CRectangle можно использовать для создания прямоугольника.

void main()

{

//...

CRectangle Rect;

Rect.SetCoord (25,25,100,100); // установка координат прямоугольника

Rect.Draw (); // отображение прямоугольника

// ...

};

В этой главе (в параграфе «Конструкторы») вы узнаете, как инициализировать переменные при создании экземпляра класса.

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

void GetCoord (int L, int Т, int R, int B)

{

*L = Left;

*T = Top;

*R = Right;

*B = Bottom;

}

Эта функция также должна быть добавлена в раздел public определения класса. Ниже приведено законченное определение класса Rectangle, содержащее новые функции-члены SetCoord и GetCoord.

#include <Stdlib.h>

class Rectangle ,

{

private: