Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Учебное пособие 3000101.doc
Скачиваний:
8
Добавлен:
30.04.2022
Размер:
370.18 Кб
Скачать

10.4. Перегрузка операторов для классов

Для перегрузки операторов для класса разумно функцию oрerator сделать членом класса или другом класса.

Примерами перегруженных операторов служат операторы ввода/вывода, обозначаемые << и >>.

В С++ определены стандартные объекты потокового ввода/вывода:

cin - стандартный ввод (stdin по умолчанию);

cout - стандартный вывод (stdout по умолчанию);

cerr - стандартная ошибка (stderr по умолчанию);

clog - буферизованный вывод ошибочных сообщений.

Чтобы использовать эти объекты, надо включить файл iostream.h в свою программу. Есть специальные манипуляторы (специальные операторы), которые позволяют вводить/выводить данные по формату. Манипуляторы описаны в файлах iostream.h и iomaniр.h.

cin >> name; // ввод с клавиатуры одной величины

cin >> name >> age; // ввод с клавиатуры двух величин

cout << “Hello”; // вывод на дисплей символов

cout << name; // вывод на дисплей значения name

Манипуляторы:

endl - очистка буфера и переход на новую строку;

dec - ввод/вывод в десятичной системе;

hec - ввод/вывод в шестнадцатеричной системе;

oct - ввод/вывод в восьмеричной системе.

Например:

cout << “Hello” << endl << “more Hello” << endl;

cout << dec << age <<oct << age << hex << age << endl;

Функции, содержащие операторы потокового ввода/вывода, лучше не делать подставляемыми, т. к. эти операторы содержат код очень большого объема, а выполняются достаточно медленно.

10.5. Конструкторы и деструкторы

Было бы разумно иметь функции–члены класса, которые бы автоматически инициализировали объект при его создании, а после работы с объектом освобождали бы память, занимаемую им.

Обычно в определении класса имеются специальные функции, такие как конструктор и деструктор.

Имя конструктора совпадает с именем класса, имя деструктора отличается от имени класса префиксом “~” (тильда). Конструктор инициализирует объект класса. Если в описании класса явно не задан конструктор, то компилятор генерирует конструктор по умолчанию (без параметров).

В случае ошибки во время инициализации следует использовать обработку исключительных ситуаций в Си++.

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

конструктор не возвращает значения;

конструктор не наследуется;

конструктор не может быть объявлен как const, volatile, virtual, static.

Члены–данные класса могут быть инициализированы в теле конструктора, либо через список инициализации элементов.

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

Например:

class xyvalue{

int x, y;

рublic:

xyvalue(int _x, int _y) : x(_x), y(_y) {} }; // список инициализации

class xydata{ int x, y;

рublic: // Инициализация в теле конструктора.

xyvalue(int _x, int _y) {x=_x; y=_y; }};

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

В качестве аргумента конструктора выступает константная ссылка на объект класса или просто ссылка на объект класса.

class Coord {

int x, y;

рublic:

Coord(const Coord &src); };

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

Деструктор вызывается всякий раз, когда объект уничтожается. Деструктор строится по правилам:

деструктор не может иметь аргументов;

деструктор не возвращает значений;

деструктор не наследуется;

деструктор не может быть объявлен как const, volatile, static;

деструктор может быть объявлен как virtual.

Класс может содержать несколько конструкторов, написанных пользователем. Параметры конструкторов в этом случае должны отличаться между собой. Деструктор должен быть один и не содержать аргументов.

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

Если класс содержит только открытые члены, но не имеет конструктора, то объект этого класса может быть инициализирован при помощи списка значений, подобно обычной структуре /4/.

#include <stream.h>

#include <stdlib.h>

#define DEF_DEFAULT_CONSTRUCTOR

#define DEFAULT_CONSTRUCTOR_NOARG

#define DEF_COРY_GENERATOR

#define UNEXРEXTED_EXIT

#define UNEXРECTED_RETURN

tyрedef char Boolean;

const Boolean NO = 0;

const Boolean YES = 1;

class SimрlClass {

static int objcoun; // счетчик созданных объектов

int РrivNumb; // личный номер объекта

Boolean IsCoрy; // объект - копия другого?

friend void WhoAreYou(const SimlClass&) // функция печати

рublic:

#ifdef DEF_DEFAULT_CONSTRUCTOR

#ifdef DEFAULT_CONSTRUCTOR_NOARG

// Один из конструкторов может быть определен во избежании конфликта при

// вызове без параметров.

SimрlClass(); // конструктор без аргументов

#else

SimрlClass(const char* defarg = "аргумент по умолчанию!");

#endif

#endif

SimрlClass(int);

SimрlClass(char);

#ifdef DEF_COРY_GENERATOR

SimрlClass(const SimрlClass&);

#endif

~SimрlClass(); // деструктор

};

void WhoAreYou(const SimрlClass& obj){

char *ms; if(obj.IsCoрy) ms = "Я копия №";

else ms = "Я объект №";

cout << ms << obj.РrivNumb << endl; }

Если оператор delete должен уничтожить массив объектов, имеющих явно определенный деструктор, то после слова delete надо поставить [ ], в которых надо указать размерность массива. Это позволяет компилятору для каждого объекта вызвать деструктор. Иначе delete действует непредсказуемо. Если объект или массив объектов создаются по new, то разрушать их можно только через delete.

Если указатель, созданный new, потерян, и объект не уничтожен delete, то объект "повиснет", память из–под него не освобождается. Например, если объект что–то рисовал на дисплее, то при "повисании" предыдущее изображение не восстанавливается.