Свод ситуаций, при которых вызываются конструкторы и деструкторы 


Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Свод ситуаций, при которых вызываются конструкторы и деструкторы



 

Обычный конструктор (не копирования) вызывается:

 

1) при создании объекта (при обработке описания объекта);

 

2) при создании объекта в динамической памяти (с использованием опе-рации new). При этом в динамической памяти предварительно отводится необходимый по объему фрагмент памяти;

 

3) при композиции объектов;

 

4) при создании объекта производного класса.

 

Замечание. Если в программе создается не единичный(скалярный)объект,амассив объектов, то в соответствующем классе (структуре) должен быть конст-руктор умолчания (явно или неявно сгенерированный). Действительно, при объ-явлении массива объектов или создании массива в динамической памяти указы-вается размерность массива, что несовместимо с заданием параметров для кон-структора преобразования или конструктора с двумя и более параметрами:

 

class X{...};X* x1 = new X[10];

 

Как уже было указано, если в классе явно описан хотя бы один конструктор, то конструктор умолчания не генерируется системой неявно. Для удаления такого массива должна применяться векторная форма операции delete, при исполь-зовании которой деструктор вызывается для каждого элемента массива:

 

delete [] x1;

 

Конструктор копирования вызывается:

 

1) при инициализации создаваемого объекта:

 

box a(1,2,3); // вызов конструктора с тремя параметрами
box b = a; // инициализация

 

2) при инициализации временным объектом: box c = box(3,4,5);

 

3) при передаче параметров-объектов в функцию по значению: int f(box b);

4) при возвращении результата работы функции в виде объекта. box f ();

 

Примечание 1. Если используется оптимизирующий компилятор,то при обра-ботке инициализации вида:

box c = box(3,4,5)

 

временный объект не создается, и вместо конструктора копирования используется кон-

 

структор с тремя параметрами:

 

(box c(3,4,5)).

 

Примечание 2. Если при возвращении результата работы функции в виде объектатип возвращаемого значения не совпадает с типом результата работы функции, то вы-зывается не конструктор копирования, а конструктор преобразования или функция преобразования (описывается ниже). Данное преобразование выполняется, если оно однозначно. Иначе фиксируется ошибка.

 

Пример:

 

class Y; class X{

...

public:

 

X(const Y& y1);

 

...

 

};

 

class Y{

 

...

 

public:

 

...

 

X f(){

...

return *this;

 

}

 

};

 

X::X(const Y& y1)

 

{...}

 

Деструктор вызывается:

 

1) при свертке стека – при выходе из блока описания объекта, в частности, при обработке исключений (при выходе из try -блока по оператору throw, try -блоки описываются далее),завершении работы функций;

 

2) при уничтожении временных объектов – сразу, как только завершится конструкция, в которой они использовались;

 

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

 

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

 

Примечание. Все правила описания и использования конструкторов и деструк-торов применимы и для структур.

Статические члены класса

 

Информационные члены класса, которые могут быть представлены в един-ственном экземпляре для всех объектов данного типа, в случае такого представ-ления называются статическими членами. Они не являются частью объектов этого класса и размещаются в статической памяти. Для их описания используется служебное слово static.

 

Для всех объектов, созданных на основе класса, содержащего статический член, существует только одна копия этого члена. Примером такого статического члена является счетчик числа созданных объектов данного класса. Такой счетчик может существовать только в отрыве от всех экземпляров объектов данного класса, в то же время работать с ним обычно приходится одновременно с вызовом обычных методов, например, конструкторов объектов, поэтому описывать счет-чик удобнее именно как элемент класса.

 

Статическими могут быть не только информационные члены класса, но и его методы. Статический метод не может использовать никакие нестатические члены класса, так как, являясь частью класса, а не объекта, он не имеет неявного пара-метра this. Поскольку статический метод не использует специфического со-держимого конкретного объекта, то обращение к нему может осуществляться не только с использованием идентификатора объекта, но и с использованием иден-тификатора класса:

 

имя_класса:: имя_функции (фактические_параметры);

 

Одно из очевидных применений статических методов – манипуляция гло-бальными объектами и статическими полями данных соответствующего класса.

 

Примечание 1. Статические методы класса не могут вызывать нестатические,таккак последние имеют доступ к данным конкретных объектов. Обратное допустимо: не-статические методы могут вызывать статические методы.

 

Примечание 2. Статический метод класса может создавать объекты данного илюбого другого класса. Это можно использовать, в частности, если необходимо в про-грамме запретить создание объектов простым объявлением или с использованием опе-рации new. В этом случае конструктор и деструктор помещаются в закрытую область класса, а для создания и уничтожения объекта используются специальные статические методы, которые можно вызывать, не имея ни одного объекта.

 

Примечание 3. Статические методы класса не могут быть виртуальными и кон-стантными (inline–функциями быть могут).

 

Пример:

 

#include <iostream> using namespace std;

 

class X{X(){} ~X(){}

 

public:

 

static X& createX(){

 

X* x1 = new X;

 

cout << "X created" << endl; return *x1;

}

 

static void destroyX(X& x1){ delete &x1;

 

cout << "X destroyed" << endl;

 

}

 

};

 

int main(){

 

X& xx1 = X::createX();

 

...

 

X::destroyX(xx1); return 0;

}

 

Статические информационные члены класса, даже находящиеся в закрытой области (а это характерно для информационных членов класса в соответствии с принципом инкапсуляции), необходимо объявить дополнительно вне класса (с возможной инициализацией):

 

тип_переменной имя_класса:: идентификатор = инициализатор;

 

Это связано с тем, что память для статического объекта должна быть выде-лена до начала работы программы. В то же время при обработке описания класса до создания конкретных объектов никакие области памяти не отводятся. В даль-нейшем прямое обращение к статическим информационным членам, находя-щимся в закрытой секции, недопустимо. Если инициализация не нужна, то все равно необходимо дополнительное объявление статического члена вне класса для резервирования памяти для статического члена. В противном случае на этапе сборки исполняемого модуля будет выдана ошибка о неразрешенной внешней ссылке.

 

Пример:

 

class B {

 

static int i; // статический информационный член

// класса

 

public:

 

static void f(int j){ //статический методi = j;

 

}

 

};

 

int B::I = 10; // дополнительное внешнее определение

 

// статической переменной с

// инициализацией статического

// информационного члена класса b.

 

int main(){B a;

...

 

B::f(1); // вызов статической функции-члена класса.

 

...

 

return 0;

 

}

 



Поделиться:


Последнее изменение этой страницы: 2017-02-05; просмотров: 124; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.145.23.123 (0.014 с.)