Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
КРАТКИЙ ОБЗОР С.doc
Скачиваний:
1
Добавлен:
26.10.2018
Размер:
2.11 Mб
Скачать

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

      Если у класса есть конструктор, он вызывается всякий раз при       создании объекта этого класса. Если у класса есть деструктор,       он вызывается всякий раз, когда уничтожается объект этого класса.       Объект может создаваться как:       [1] автоматический, который создается каждый раз, когда его       описание встречается при выполнении программы, и уничтожается       по выходе из блока, в котором он описан;       [2] статический, который создается один раз при запуске программы       и уничтожается при ее завершении;       [3] объект в свободной памяти, который создается операцией new       и уничтожается операцией delete;       [4] объект-член, который создается в процессе создания другого       класса или при создании массива, элементом которого он       является.       Кроме этого объект может создаваться, если в выражении явно       используется его конструктор ($$7.3) или как временный объект       ($$R.12.2). В обоих случаях такой объект не имеет имени. В следующих       подразделах предполагается, что объекты относятся к классу с       конструктором и деструктором. В качестве примера используется       класс table из $$5.3.1.

5.5.1 Локальные переменные

      Конструктор локальной переменной вызывается каждый раз, когда при       выполнении программы встречается ее описание. Деструктор локальной       переменной вызывается всякий раз по выходе из блока, где она       была описана. Деструкторы для локальных переменных вызываются в       порядке, обратном вызову конструкторов при их создании:       void f(int i)       {       table aa;       table bb;       if (i>0) {       table cc;       // ...       }       // ...       }       Здесь aa и bb создаются (именно в таком порядке) при каждом вызове       f(), а уничтожаются они при возврате из f() в обратном порядке -       bb, затем aa. Если в текущем вызове f() i больше нуля, то cc       создается после bb и уничтожается прежде него.       Поскольку aa и bb - объекты класса table, присваивание aa=bb       означает копирование по членам bb в aa (см. $$2.3.8). Такая       интерпретация присваивания может привести к неожиданному (и обычно       нежелательному) результату, если присваиваются объекты класса,       в котором определен конструктор:       void h()       {       table t1(100);       table t2 = t1; // неприятность       table t3(200);       t3 = t2; // неприятность       }       В этом примере конструктор table вызывается дважды: для t1 и t3.       Он не вызывается для t2, поскольку этот объект инициализируется       присваиванием. Тем не менее, деструктор для table вызывается три       раза: для t1, t2 и t3! Далее, стандартная интерпретация       присваивания - это копирование по членам, поэтому перед выходом       из h() t1, t2 и t3 будут содержать указатель на массив имен, память       для которого была выделена в свободной памяти при создании t1.       Указатель на память, выделенную для массива имен при создании       t3, будет потерян. Этих неприятностей можно избежать (см. $$1.4.2       и $$7.6).