
Лабораторная работа №16
Обзор языка С++. Классы
Цель работы: научиться создавать и использовать классы при составлении простых программ.
Краткие теоретические сведения
Что такое класс?
Класс, как и структура, представляет собой набор данных и функций, предназначенных для совместного выполнения определенной задачи. Как говорят, класс инкапсулирует задачу. Классы имеют следующие характерные элементы:
Средства контроля доступа
Конструкторы
Деструкторы
Члены-данные
Функции-члены
Специальный скрытый указатель с именем this.
Анатомия класса
Класс, как и структура, должен быть предварительно объявлен. Объявление класса обычно содержится в заголовочном файле. Для простых классов объявление и определение могут быть размещены в единственном исходном файле программы, однако при написании реальных программ так обычно не поступают. Как правило, для класса создают отдельный исходный файл с именем, близким к имени класса, и расширением .срр. Заголовочный файл для класса обычно имеет то же имя, что и исходный файл, но расширение .h. Например, если у вас есть класс с именем MyClass, исходный файл следует назвать MYCLASS.CPP, а заголовочный — MYCLASS. H.
Уровни доступа к членам класса
Члены классов могут иметь три уровня доступа: закрытый (private), открытый (public) или защищенный (protected).
Уровни доступа к членам класса определяют способ работы пользователей с классом. Программируя самостоятельно, вы можете быть как создателем классов, так и их пользователем. При работе в команде один программист может быть создателем класса, а остальные — его пользователями.
Чтобы понять роль уровней доступа, прежде всего нужно разобраться в том, как используются классы. Любой класс содержит открытую часть, к которой возможен доступ извне класса, и закрытую часть. Закрытая часть класса определяет его внутреннюю реализацию. В хорошо спроектированном классе от пользователя скрыто все, что ему не требуется знать.
Абстрактное представление данных (data abstraction) — это закрытие внутренней реализации свойств класса от взгляда извне.
Абстрактное представление данных дает пользователю возможность знать о классе ровно столько, сколько необходимо, и предохраняет от вмешательства туда, куда вмешиваться не следует. Внутренняя работа класса закрыта, тогда как интерфейс пользователя является открытым.
К защищенным членам класса, как и к закрытым, пользователь обращаться не может. Однако эти члены могут быть доступны для классов, которые являются производными данного класса.
В языке С++ есть три ключевых слова, устанавливающих уровни доступа. Это (как и следовало ожидать) слова public, private и protected. Уровни доступа к членам класса устанавливаются при объявлении класса. Для объявления класса служит ключевое слово class. Объявление класса выглядит подобно объявлению структуры, но с добавлением модификаторов доступа:
class Rect {
public:
int GetWidth();
int GetHeight();
void SetRect(int _left, int _top, int _bottom, int _right);
private:
int left;
int top;
int bottom;
int right;
};
Класс Rect служит для представления прямоугольника.
Обратите внимание, как организовано разбиение членов класса по уровням доступа. Вы не обязаны использовать все три уровня доступа в своих классах. При желании можно вообще не устанавливать уровни доступа, но обычно у вас будут присутствовать по крайней мере два из них — public и private.
По умолчанию члены класса имеют уровень доступа private. Если вы не используете при о6ъявлении модификаторы доступа, все данные и функции класса будут закрытыми. Такие классы в большинстве случаев не очень полезны.
Конструкторы
Классы в С++ имеют специальную функцию, называемую конструктором.
Конструктор (constructor) — это функция, которая автоматически вызывается при создании экземпляра класса.
Конструктор используется для инициализации переменных-членов класса, выделения необходимой памяти и выполнения других действий, необходимых перед началом использования класса. Если класс не содержит явно определенного конструктора, компилятор C++Builder создает конструктор по умолчанию (default constructor). Для простых классов это вполне допустимо, но обычно конструкторами снабжают классы любой значимости. Имя конструктора должно совпадать с именем класса. Это служит отличительным признаком конструктора. Теперь, имея все это в виду, давайте добавим объявление конструктора в класс Rect:
class Rect {
public:
Rect();
Rect(int _left, int _top, int _bottom, int _right);
int GetWidth();
int GetHeight();
void SetRect(int _left, int _top, int _bottom, int _right);
private:
int left;
int top;
int bottom;
int right;
};
Обратите внимание, что для конструктора не указан тип возвращаемого значения. Дело в том, что конструктор не может возвращать никакого значения. Если вы попытаетесь указать тип возвращаемого значения в объявлении конструктора, компилятор выдаст сообщение об ошибке.
Конструкторы можно определить следующим образом:
Rect::Rect( )
{ left = 0;
top = 0;
bottom = 0;
right = 0;
}
Rect::Rect(int _left, int _top, int _bottom, int _right)
{ left = _left;
top = _top;
bottom = _bottom;
right = _right;
}
Первый конструктор является конструктором по умолчанию, поскольку он не имеет аргументов. Его задача – просто инициализировать нулем все члены-данные. Второй конструктор принимает переданные ему значения и присваивает их соответствующим членам-данным.
Списки инициализаторов
Си++ дает возможность инициализировать члены-данные класса при помощи списка инициализаторов (initializer list).
Деструкторы
Деструктор (destructor) — это специальная функция, которая автоматически вызывается перед уничтожением объекта.
Деструктор можно рассматривать как противоположность конструктору.
Как было сказано, деструктор вызывается непосредственно перед разрушением класса. Класс может быть разрушен либо при выходе из области видимости (в случае размещения в стеке), либо в результате применения оператора delete (в случае динамического размещения). В любом случае, вызов деструктора будет последним действием перед окончательным исчезновением класса.
Члены-данные
Члены-данные класса — это просто переменные, объявленные ASCII-кодв описании класса. Их областью видимости по умолчанию является класс. Вы можете управлять доступом к членам-данным класса, объявляя их как private, public или protected. Независимо от установленного уровня доступа, члены-данные класса могут использоваться всеми функциями этого класса. Уровень доступа определяет видимость членов-данных вне класса. Например, к закрытым или защищенным членам-данным доступ извне невозможен. Обращение к открытым членам-данным возможно только через класс. Рассмотрим, например, класс Rect, объявленный ранее. В нем отсутствуют открытые члены-данные. При попытке обращения к переменным этого класса вы получите сообщение об ошибке:
Rect rect(10, 10, 200, 200);
int x = rect.left; // ошибка компиляции!
Компилятор выдаст сообщение Rect::left is not accessible (Rect::left недоступен). Это означает, что left является закрытым членом класса и вы не можете обращаться к нему из программы. Если переменную left объявить в разделе public, то компиляция пройдет успешно.
Для работы с закрытыми членами-данными вы можете написать специальные функции. Одна функция будет возвращать значение определенного члена класса, а другая — изменять его значение. Это открытые функции-члены, работающие с закрытыми членами-данными.
Правила работы с членами-данными класса
Используйте столько членов-данных, сколько необходимо для нормального функционирования класса, но старайтесь по возможности обходиться локальными переменными.
Не делайте все члены-данные открытыми.
Используйте функции для обращения к закрытым членам-данным, которые должны быть доступны
Контролируйте значения, присваиваемые закрытым членам-данным с помощью функций, чтобы избежать неправильного ввода.
Инициализируйте все члены-данные либо в списке инициализаторов, либо в теле конструктора.
Не забывайте уничтожать члены-данные, размещаемые в памяти динамически.