Бьерн Страуструп. Язык программирования С++ Второе дополненное издание



Pdf көрінісі
бет110/256
Дата11.07.2022
өлшемі2,87 Mb.
#37591
1   ...   106   107   108   109   110   111   112   113   ...   256
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() 



Бьерн Страуструп.
Язык программирования С++ 
 
143 
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). 


Достарыңызбен бөлісу:
1   ...   106   107   108   109   110   111   112   113   ...   256




©emirsaba.org 2024
әкімшілігінің қараңыз

    Басты бет