КАТЕГОРИИ:
АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника
|
Имя_класса
У деструктора не может быть параметров (даже типа void), и деструктор не имеет возможности возвращать какой-либо результат, даже типа void. Статус доступа деструктора по умолчанию public (т.е. деструктор доступен во всей области действия определения класса). В несложных классах деструктор обычно определяется по умолчанию. Деструкторы не наследуются, поэтому даже при отсутствии в производном классе деструктора он не передается из базового, а формируется компилятором как умалчиваемый со статусом доступа public. Этот деструктор вызывает деструкторы базовых классов.
Деструкторы базовых классов выполняются в порядке, обратном перечислению классов в определении производного класса. Таким образом порядок уничтожения объекта противоположен по отношению к порядку его конструирования. Вызовы деструкторов для объектов класса и для базовых классов выполняются неявно. Однако вызов деструктора того класса, объект которого уничтожается в соответствии с логикой выполнения программы, может быть явным. Это может быть, например, случай, когда при создании объекта для него явно выделялась память.
Основные свойства и правила использования деструкторов:
· Деструктор имеет то же имя, что и класс, в котором он объявляется, с префиксом ~(тильдой); · Деструктор не возвращает значения даже типа void; · Деструктор не наследуется в производных классах; · Производный класс может вызвать деструкторы для его базовых классов; · Деструктор не имеет параметров (аргументов); · Класс может иметь только один деструктор; · Деструктор - это функция, и он может быть виртуальным, его можно объявить виртуальным; · невозможно получить в программе адрес деструктора (указатель на деструктор); · Если деструктор не задан в программе, то он будет автоматически сгенерирован компилятором для уничтожения соответствующих объектов. Все деструкторы, сгенерированные компилятором, имеют атрибут public; · Деструктор вызывается автоматически при разрушении объекта; · Когда вызывается библиотечная функция exit, вызываются деструкторы только для глобальных объектов; · Когда вызывается библиотечная функция abort, никакие деструкторы не вызываются.
Объекты могут быть переданы в функции тем же способом, что и переменные любого другого типа. Объекты передаются функциям с использованием стандартного механизма передачи по значению. Это означает, что создается копия объекта, которая и передается функции. Однако тот факт, что создается копия, означает по существу, что создается другой объект. При создании копии объекта для передачи ее в функцию конструктор объекта не вызывается. Однако, когда копия объекта внутри функции уничтожается, деструктор вызывается. По умолчанию при создании копии объекта появляется его побитовая копия. Это означает, что новый объект служит точным дубликатом оригинала. Тот факт, что создается точная копия, может в некоторых случаях служить источником для беспокойства. Хотя для передачи объекта в функцию используется обычный механизм передачи по значению, который в теории защищает и изолирует вызываемый аргумент, остается возможность побочных эффектов, в результате которых может быть поврежден объект, используемый как аргумент. Например, если некоторый объект, используемый как аргумент, резервирует память и освобождает эту память при своем уничтожении, тогда его локальная копия внутри функции освободит ту же самую память при вызове деструктора. В результате исходный объект окажется поврежденным и по существу бесполезным. Можно предотвратить возникновение подобных проблем с помощью определения оператора копирования для собственного класса путем создания специального типа конструктора, который называется конструктором копирования.
7. Дружественные функции. Функция, не являющаяся членом класса, может иметь доступ к его частным членам в случае, если она объявлена другом (friend) класса. Например, в следующем примере функция frd() объявлена другом класса cl: class cl { Как можно видеть, ключевое слово friend предшествует объявлению функции. Одна из причин, почему язык С++ допускает существование функций-друзей, связана с той ситуацией, когда два класса должны использовать одну и ту же функцию. Имеется два важных ограничения применительно к дружественным функциям. Первое заключается в том, что производные классы не наследуют дружественных функций. Второе заключается в том, что дружественные функции не могут объявляться с ключевыми словами static или extern.
8. Иерархия классов.
Иерархия классов возникает в программе за счет механизма наследования, реализованного в Си++. Наследование – это процесс, посредством которого один объект может приобретать свойства другого. Так как объекты принадлежат к классам, то между классами в этом случае устанавливаются определенные взаимоотношения. Класс, который делегирует свойства, называется базовым (base), а который наследует свойства – производным (derived). У одного базового класса может быть несколько производных, и наоборот, один производный класс может наследовать характеристики нескольких базовых классов. Схемные примеры наследования:
а) В1 б) В1 В2 в) В1
Д1 Д1 Д Д2 В примере (а) показана простейшая схема подчиненности с одним базовым (В1) и одним производным (Д1) классом. В примере (б) показан один производный (Д) класс от двух базовых (В1 и В2). На схеме (в) показано, что В1 есть базовый класс для Д1, который в свою очередь является базовым для Д2. В этом последнем случае В1 называется для Д2 косвенно-базовым. Взаимосвязи классов в программе образуют иерархию классов. При указании наследования соблюдаются следующие правила. Базовый класс описывается обычным образом. Например: class base { //содержание класса base }; Для указания наследования после имени производного класса ставится двоеточие и указывается имя базового класса со спецификатором доступа(private, public). Для примера (а) описание будет выглядеть следующим образом: class derived: public base { //содержание класса derived }; Спецификатор выбирается в зависимости от того, как предполагается использовать члены класса base. Для примера (б) описание производного класса будет выглядеть, например, так: class derived: public В1, public В2 { //содержание класса derived }; В примере (в) для производного класса Д2 базовым будет класс Д1, поэтому описание Д2 соответствует схеме (а). Преимущества, получаемые от механизма наследования: 1) повторное использование данных и функций, ранее созданных в базовом классе, без их дублирования в производном классе; 2) получение более компактной и обозримой программы; 3) повышение степени защищенности закрытых членов базового класса; 4) адекватность программной модели предметам реального мира. 9. Наследование. Технология доступа к членам классов.
Базовый класс является первым в иерархии, он «не знает» сколько у него будет производных классов (или не будет вообще). Поэтому 1) он проектируется самодостаточным в плане доступа к закрытым членам и 2) чле-ны производных классов в нем не упоминаются. Как известно, внутрикласса его члены открыты друг для друга: любая функция-член может обращаться к любой переменной-члену класса. Однако извнеможно обратиться только к открытым членам класса. Важно отметить, что при расследовании производный класс полностью включает в себя базовый класс. Однако не все члены классов открыты друг для друга в этом объединении. Здесь необходимо следовать следующим правилам. 1.«Круг общения» членов производного класса расширяется только за счет publiс-членов базового класса. Это означает, что члены производного класса могут обращаться напрямую только к открытым членам класса base; private-члены базового класса можно использовать в описании функций производного класса только через открытые члены base class.
#include <iostream.h>
|