Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Язык программирования С++ и его «подводные камни».DOC
Скачиваний:
39
Добавлен:
01.05.2014
Размер:
1.02 Mб
Скачать

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

Среди всех методов любого класса выделяются два, которые определяют, каким образом объекты класса создаются, инициализируются, копируются и разрушаются. Речь идет о конструкторах (constructor) идеструкторах (destructor), которые наряду с ха­рак­те­рис­ти­ка­ми обычных методов обладают и некоторыми уникальными свойствами:

– конструктор всегда имеет то же имя, что и сам класс; это же относится и к деструктору, которому, однако, предшествует символ ~ (тильда);

– не имеют объявлений о типе возвращаемых значений (даже void);

– не могут быть унаследованы, хотя производный класс может вызывать конструкторы и деструкторы базового класса;

– конструкторы, как и большинство функций С++, могут иметь аргументы по умолчанию или использовать списки инициализации элементов;

– деструкторы могут иметь атрибут virtual, а конструкторы нет;

– нельзя работать с их адресами;

– если конструкторы или деструкторы не были определены явно, они ге­нерируются ком­пи­ля­тором;

– конструктор нельзя вызывать как обычную функцию; вызов деструктора возможен с пол­но­стью уточнённым именем;

– при определении и разрушении объектов вызов конструкторов и дест­рукторов осу­ще­ствля­ется автоматически;

– конструкторы и деструкторы, при необходимости выделения объекту па­мяти, могут вы­пол­нять явные вызовы операций new и delete.

Прежде чем переходить к более подробному знакомству с этими специаль­ными методами классов, рассмотрим правила, по которым происходит соз­дание/уничтожение объектов:

– конструкторы и деструкторы автоматически запускаются всякий раз при создании и разрушении объектов;

– глобальные и локальные статические объекты создаются в начале вы­полнения программы – до того, как управление попадает в функцию main (или WinMain). Уничтожение таких объектов происходит в момент завершения программы в результате возврата из функции main (WinMain);

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

– конструктор объекта, память которому выделяется в куче (посредством операции new), вызывается автоматически при вызове new; такой объект разрушается при явной передаче объекта в оператор delete.

Примечание

Для объектов, память под которые выделяется вызовом malloc (или аналогич­ной функции), конструктор не вызывается вообще, поскольку в этом случае функция просто не знает, какой конструктор надо запустить (эта функция не принимает никакой информации о типе).

Рассмотрим простой пример, для которого воспользуемся классической функцией main, чтобы избежать дополнительных действий, необходимых для Windows-приложений:

Пример 2.2

#include <stdio.h>

#include <string.h>

// Объявляем класс

class sample {

private: // К этим данным доступ возможен только посредством методов класса

char * StrName;

public: // К этим данным доступ возможен из любого места программы

// Определяем простой конструктор

Sample (char * str) {

strName = new char[strlen(str) + 1];

strcpy(strName, str);

printf(“Entry in constructor for %s\n”, strName);

}

// Определяем деструктор

~Sample( ){

printf(“Entry in destructor for %s\n”, strName);

delete strName;

strName = 0;

}

// Определяем первый глобальный объект

Sample global1(“global #1”);

// "Глупая" функция, иллюстрирующая создание автоматического объекта

void Sillyfunc( ) {

// Определяем объект, локальный для данной функции

Sample fnAuto (“automatic function”);

printf(“Function SillyFunc()\n”);

}

int main(int argc, char *argv[])

{

// Определяем первый локальный объект

Sample auto1(“automatic #1”);

printf(“Begin main()\n”);

SillyFunc( );

// Определяем второй локальный объект

Sample auto2(“automatic #2”);

printf(“Continue main()\n”);

return o;

}

// Определяем второй глобальный объект

Sample global2(“global #2”);

Результат выполнения этой программы будет выглядеть следующим образом:

Entry in constructor for global #1

Entry in constructor for global #2

Entry in constructor for autimatic #1

Begin main()

Entry in constructor for automatic function

Function SillyFunk()

Entry in destructor for automatic function

Entry in constructor for autimatic #2

Continue main()

Entry in destructor for automatic #2

Entry in destructor for automatic #1

Entry in destructor for global #2

Entry in destructor for global #1

Обратите внимание на последовательность создания и разрушения глобальных и автоматических объектов.

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

Примечание

Единственным ограничением на аргументы конструктора является то, что в ка­честве их нельзя использовать объект того же класса. Вместо этого можно ис­пользовать ссылку на объект.

Некоторые конструкторы играют особую роль.