Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
###Cpp_лкц1_1.09_11_#дляБАК#29_01_12.doc
Скачиваний:
40
Добавлен:
29.04.2019
Размер:
6.42 Mб
Скачать

Часть II. Объектно-ориентированное программирование

class monstr{

friend int steal_ammo(monstr &);

friend void hero::kill(monstr &);

//' Класс hero должен быть определен ранее

}:

int steal_ammo(monstr &M){return --M.ammo;}

void hero::kill(monstr &M){M.health = 0: M.ammo = 0;}

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

Дружественный класс

Если все методы какого-либо класса должны иметь доступ к скрытым полям другого, весь класс объявляется дружественным с помощью ключевого слова friend. В приведенном ниже примере класс mistress объявляется дружественным классу hero:

class hero{

friend class mistress:

}

class mistressf

void fl():

void f2(); } Функции f 1 и f2 являются дружественными по отношению к классу hero (хотя и описаны без ключевого слова friend) и имеют доступ ко всем его полям.

Объявление friend не является спецификатором доступа и не наследуется.

ПРИМЕЧАНИЕ

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

Деструкторы

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

  • для локальных объектов — при выходе из блока, в котором они объявлены;

  • для глобальных — как часть процедуры выхода из main:

  • для объектов, заданных через указатели, деструктор вызывается неявно при использовании операции delete.

Глава 4. Классы

189

ВНИМАНИЕ

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

Имя деструктора начинается с тильды (~), непосредственно за которой следует имя класса. Деструктор:

  • не имеет аргументов и возвращаемого значения;

  • не может быть объявлен как const или static;

  • не наследуется;

  • может быть виртуальным (см. раздел «Виртуальные методы», с. 205).

Если деструктор явным образом не определен, компилятор автоматически создает пустой деструктор.

Описывать в классе деструктор явным образом требуется в случае, когда объект содержит указатели на память, выделяемую динамически — иначе при уничтожении объекта память, на которую ссылались его поля-указатели, не будет помечена как свободная. Указатель на деструктор определить нельзя.

Деструктор для рассматриваемого примера (с. 183) должен выглядеть так:

monstr::-monstrО {delete [] name;}

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

monstr *m; ... m -> -monstrO;

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

Перегрузка операций

C++ позволяет переопределить действие большинства операций так, чтобы при использовании с объектами конкретного класса они выполняли заданные функции. Эта дает возможность использовать собственные типы данных точно так же, как стандартные. Обозначения собственных операций вводить нельзя. Можно перегружать любые операции, существующие в C++, за исключением:

.* ?: # ## sizeof

Перегрузка операций осуществляется с помощью методов специального вида {функций-операций) и подчиняется следующим правилам:

  • при перегрузке операций сохраняются количество аргументов, приоритеты операций и правила ассоциации (справа налево или слева направо), используемые в стандартных типах данных;

  • для стандартных типов данных переопределять операции нельзя;

190