Справочник по C/C++
Конструкторы и деструкторы

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

Класс может включать функцию конструктора и функцию деструктора. Конструктор вызывается при первоначальном создании объекта класса, а деструктор — при разрушении. Имя конструктора совпадает с именем класса. Функция деструктора имеет имя совпадающее с именем класса, но ему предшествует символ тильда (~). Следующий пример создаёт точку на плоскости с координатами по умолчанию (0; 0), а при уничтожении выводит сообщение.

class point{
	int x, y;
public:
	point (int mx = 0, int my = 0){
		x = mx;
		y = my;
	}
	~point (void){
		cout << "точка уничтожена";
	}
};

Спецификатор expliclt

Спецификатор expliclt применяется только к конструкторам. Конструктор, определённый с помощью спецификатора expliclt, будет использоваться только в том случае, если инициализация в точности совпадает с тем, что задано конструктором. Никаких автоматических преобразований выполнено не будет (т.е. спецификатор expliclt создаёт "неконвертирующий конструктор").

Порядок вызова конструкторов

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

При множественном наследовании, при объявлении производного класса базовые классы перечисляются через запятую. Причём при создании объекта конструкторы выполняются в порядке следования базовых классов слева направо. Например.

class B1{
public:
	B1(){ cout << "B1 "; }
};
class B2{
public:
	B2(){ cout << "B2 "; }
};
class D: B1, B2{
public:
	D(){ cout << "D"; }
};

D d;	//создание объекта
Выведет: "B1 B2 D".

Виртуальные деструкторы

Довольно типичная ситуация, когда динамически создаётся объект производного класс, а указатель используется базового класса. При уничтожении объекта вызывается деструктор только базового класса. Например.

class Base{
public:
	Base(){ cout << "B "; }
	~Base(){ cout << "B "; }
};
class Derive: Base{
public:
	Derive(){ cout << "D "; }
	~Derive(){ cout << "~D "; }
};

Base *p = new Derive;
delete p;
Выведет: "B D ~B".

Чтобы не допускать таких ситуаций необходимо использовать виртуальный деструктор. Если при объявлении деструктора базового класса он объявляется как виртуальный, то все конструкторы производных классов также являются виртуальными. При разрушении объекта с помощью оператора delete через указатель на базовый класс будут корректно вызваны деструкторы производных классов.
class Base{
public:
	virtual Base(){ cout << "B "; }
	~Base(){ cout << "B "; }
};
class Derive: Base{
public:
	Derive(){ cout << "D "; }
	~Derive(){ cout << "~D "; }
};

Base *p = new Derive;
delete p;
Выведет: "B D ~D ~B".






Нет комментариев.



Оставить комментарий:
Ваше Имя:
Email:
Антибот:  
Ваш комментарий: