Индивидуальные очистные сооружения: К классу индивидуальных очистных сооружений относят сооружения, пропускная способность которых...
Типы оградительных сооружений в морском порту: По расположению оградительных сооружений в плане различают волноломы, обе оконечности...
Топ:
Комплексной системы оценки состояния охраны труда на производственном объекте (КСОТ-П): Цели и задачи Комплексной системы оценки состояния охраны труда и определению факторов рисков по охране труда...
Интересное:
Финансовый рынок и его значение в управлении денежными потоками на современном этапе: любому предприятию для расширения производства и увеличения прибыли нужны...
Мероприятия для защиты от морозного пучения грунтов: Инженерная защита от морозного (криогенного) пучения грунтов необходима для легких малоэтажных зданий и других сооружений...
Влияние предпринимательской среды на эффективное функционирование предприятия: Предпринимательская среда – это совокупность внешних и внутренних факторов, оказывающих влияние на функционирование фирмы...
Дисциплины:
2020-05-08 | 197 |
5.00
из
|
Заказать работу |
|
|
Когда создается объект типа Counter, нам хотелось бы, чтобы его поле count было инициализировано нулевым значением, поскольку большинство счетчиков начинают отсчет именно с нуля. Мы могли бы провести инициализацию с помощью вызова функции set_count() с аргументом, равным нулю, или создать специальный метод zero_count(), обнуляющий значение функции. Недостаток такого подхода заключается в том, что эти функции необходимо вызывать явно каждый раз при создании объекта типа Counter:
Counter cl: // при определении объекта
cl.zero_count(): // это необходимое действие
Подобные действия легко могут привести к неправильной работе всей программы, поскольку программисту для этого достаточно забыть проинициализировать хотя бы одну переменную после ее создания. Если в программе создается множество таких переменных, гораздо проще и надежнее было бы инициализировать их автоматически при создании. В нашем примере конструктор Counter() выполняет эти действия. Конструктор вызывается автоматически при создании каждого из объектов. Таким образом, в функции mainQ оператор
Counter cl. с2:
создает два объекта типа Counter. При создании каждого из них вызывается конструктор Counter(), присваивающий полю counter нулевое значение. Таким образом, кроме создания переменных, данный оператор еще присваивает их полям нулевое значение.
Инициализаторы в конструкторах
Главной задачей конструктора класса является инициализация данных создаваемых им объектов. Однако производить инициализацию данных при помощи оператора присваисания в теле конструктора не рекомендуется.
Инициализация осуществляется при помощи списка инициализации, расположенного между двоеточием, которое следует за закрывающей круглой скобкой в заголовке конструктора, и телом конструктора. Присваиваемые при инициализации данных значения записываются в круглых скобках после идентификаторов членов-данных и отделяются друг от друга запятыми.
|
Порядок следования идентификаторов в списке инициализации не имеет значения.
Для каждого объекта класса Counter конструктор выполняет инициализацию поля count нулем. Вы, вероятно, ожидали, что это действие будет произведено в теле конструктора приблизительно следующим образом:
count()
{ count =0; }
Такая форма записи не рекомендуется, несмотря на то, что она не содержит ошибок. Инициализация в нашем примере происходит следующим образом:
count(): count(0)
{ }
Инициализация расположена между прототипом метода и телом функции и предварена двоеточием. Инициализирующее значение помещено в скобках после имени поля.
Если необходимо инициализировать сразу несколько полей класса, то значения разделяются запятыми, и в результате образуется список инициализации:
someClass (): m1(7), m2(33), m2(4) { }
Результаты работы программы со счетчиком
В функции main() рассматриваемой нами программы создаются два объекта класса Counter с именами cl и с2. Затем на экран выводятся значения полей каждого из объектов, которые, согласно нашей задумке, должны быть инициализированы нулевыми значениями. Далее значение счетчика cl инкрементируется один раз, а значение счетчика с2 — два раза, и программа вновь заставляет объекты вывести значения своих полей на экран (что является в данном случае вполне корректным). Результат работы программы выглядит следующим образом:
cl=0
с2=0
cl=1
с2=2
Для того чтобы убедиться в том, что конструктор функционирует именно так, как мы описали выше, заставим его печатать сообщение во время выполнения:
counter(): count(0)
{ cout << "Конструктор\n": }
Теперь результат работы программы будет выглядеть следующим образом:
Конструктор
Конструктор
cl=0
с2=0
cl=1
с2=2
Как можно видеть, конструктор исполняется дважды: первый раз — для переменной cl, второй раз — для переменной с2, во время выполнения оператора
|
counter cl, с2; в функции main().
Конструктор по умолчанию
Конструктор по умолчанию — конструктор, не требующий параметров. Этот конструктор всегда должен быть определен для любого класса. Конструктор по умолчанию может не выполнять никаких действий, но чаще всего он инициализирует данные класса нулевыми значениями.
Объявление конструктора по умолчанию имеет следующий формат:
public:имя_класса ();
Например, для класса своок прототип конструктора по умолчанию записывается со спецификатором открытого доступа
public: CBook ();
Пример реализации конструктора по умолчанию ]
СВоок:: СВоок (): m_year (0), m_pTitle ("")
{ m_author [ 0 ] = ‘\0'; }
В результате работы этого конструктора будет построен объект-книга, у которого данное year получит нулевое значение, массив author начнется с нулевого байта точно так же, как и название книги, на которое указывает pTitie. Для инициализации автора не может быть использован инициализатор, так как этот член-данное объявлен в классе как символьный массив.
Конструктор с параметрами
Конструктор с параметрами инициализирует значения данных объекта значениями полученных параметров. Параметров будет столько, сколько данных необходимо проинициализировать. Прототип такого конструктора имеет формат:
public:имя_класса (список формальных параметров);
Для класса CBook конструктор с параметрами может иметь следующий прототип: CBook (char*, char*, int);
Пример реализации конструктора с параметрами
СВоок:: СВоок (char *author, char *title, int year)
: m_уеаг (year), m_pTitle (title)
{
strncpy_s (m_author, 50, author, 49);
if (strlen (author) > 49) m_author [ 49 ] = '\0';
}
В результате работы этого конструктора будет построен объект-книга, у которого данное щ_уеаг получит значение параметра year, в массив m_author будет скопировано не более 49 байтов из строки author, и указатель m_pTitie будет содержать адрес, по которому скопировано значение title.
Конструктор копирования
Конструктор копирования создает копию объекта в оперативной памяти с помощью другого объекта того же класса. В качестве параметра этот конструктор получает ссылку на объект, копию которого необходимо создать. Для конструктора копирования необходимо указать прототип следующего формата:
|
public:имя_класса (имя_класса &);
Для класса CBook конструктор копирования объявляется в спецификации класса со следующим прототипом:
СВоок (СВоок &);
Листинг 14.6. Пример конструктора копирования
СВоок:: СВоок (СВоок &о): m_year (o. m_year) {
strcpy_s (m_author, strlen (o.m_author) + 1, o.m_author);
m_pTitle = new char [strlen (o.m_pTitle) + 1 ];
strcpy_s (m_pTitle, strlen (o. m_pTitle) + 1, o. m_pTitle);
}
В результате работы конструктора копирования будет построен новый объект-книга, все члены-данные которого получат значения данных, принадлежащих копируемому объекту о, переданному по ссылке. Чтобы присвоить значение названия книги вновь создаваемому объекту, нужно сначала выделить необходимый блок памяти при помощи оператора new.
Программа EC0PYC0N демонстрирует использование копирующего конструктора по умолчанию:
// есорусо n.срр
// инициализация объектов с помощью копирующего конструктора
#include <iostream>
using namespace std;
//////////////////////////////////////////////////////////
class Distance // длина в английской системе
{
private:
int feet;
float inches;
public:
// конструктор без аргументов
Distance(): feet(0), inches(0.0) { }
// конструктора с одним аргументом нет!
// конструктор с двумя аргументами
Distance(int ft, float in): feet(ft), inches(in) { }
void getdist() // ввод длины пользователем
{
cout << "\nВведите число футов ";
cin >> feet;
cout << "Введите число дюймов: ";
cin >> inches;
}
void showdist() // вывод длины
{ cout << feet << "\'-" << inches << "'\'"; }
};
//////////////////////////////////////////////////////////
int main()
{
Distance dist1(11,6.25); // конструктор с двумя аргументами
Distance dist2(dist1); // два конструктора с одним аргументом
Distance dist3 = dist1;
// вывод всех длин
cout <<"\ndistl - ";
dist1.showdist();
cout <<"\ndist2 - ";
dist2.showdist();
cout <<"\ndist3 - ";
dist3.showdist();
cout << endl;
return 0;
}
Мы инициализировали объект distl значением 11’-6.25" при помощи конструктора с двумя аргументами. Затем мы определяем еще два объекта класса Distance с именами dist2 и dist3, оба из которых инициализируются значением объекта distl. Возможно, вам покажется, что в данном случае должен был вызваться конструктор с одним аргументом, но поскольку аргументом являлся объект того же класса, что и инициализируемые объекты, были предприняты иные действия. В обоих случаях был вызван копирующий конструктор по умолчанию. Объект dist2 инициализирован при помощи оператора
|
Distance dist2(distl):
Действие копирующего конструктора по умолчанию сводится к копированию значений полей объекта distl в соответствующие поля объекта dist2. Как это ни удивительно, но идентичные действия для пары объектов distl и dist3 выполняются при помощи оператора
Distance dist3 = distl;
Можно подумать, что данный оператор выполняет операцию присваивания, но это не так. Здесь, как и в предыдущем случае, вызывается конструктор копирования по умолчанию. Оба оператора выполняют одинаковые действия и равноправны в использовании. Результат работы программы выглядит следующим образом:
distl = 11'-6.25"
dist2 = 11"-6.25"
dist3 -=11'-6.25"
Видим, что объекты dist2 и dist3 действительно имеют те же значения, что и объект distl. В главе 11 «Виртуальные функции» мы расскажем, каким образом можно создать свой собственный копирующий конструктор с помощью перегрузки копирующего конструктора по умолчанию.
Деструктор
Деструктор (destructor) — специальный метод класса, используемый для разрушения объектов класса. Имя деструктора совпадает с именем конструктора (именем класса), которому предшествует символ тильда ~. Он всегда имеет открытый спецификатор доступа и не имеет ни типа, ни параметров. Деструктор управляет уничтожением объекта из оперативной памяти.
Вызывается деструктор автоматически при разрушении объекта. Если объект создавался динамически через указатель при помощи оператора new, то для уничтожения такого объекта следует использовать оператор delete для указателя.
Типовым использованием деструктора является освобождение динамической памяти, которая ранее была выделена конструктором.
В отличие от конструктора, деструктор не перегружается и может быть в классе только один. Лучше всегда определять деструктор класса, даже если он не производит никаких действий и имеет пустое тело.
Объявление деструктора имеет следующий формат:
public:~имя_класса ();
Например, для класса своок прототип деструктора в спецификации класса имеет вид:
~СВоок ();
СВоок:: ~СВоок () {delete [ ] m_pTitle; }
Результатом действия деструктора ~СВоок () является освобождение блока памяти с начальным адресом из itLpTitle, выделенного ранее конструктором класса.
|
|
Механическое удерживание земляных масс: Механическое удерживание земляных масс на склоне обеспечивают контрфорсными сооружениями различных конструкций...
Адаптации растений и животных к жизни в горах: Большое значение для жизни организмов в горах имеют степень расчленения, крутизна и экспозиционные различия склонов...
Кормораздатчик мобильный электрифицированный: схема и процесс работы устройства...
История развития хранилищ для нефти: Первые склады нефти появились в XVII веке. Они представляли собой землянные ямы-амбара глубиной 4…5 м...
© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!