Конструкторы и деструкторы
Конструкторы и деструкторыКласс может включать функцию конструктора и функцию деструктора. Конструктор вызывается при первоначальном создании объекта класса, а деструктор — при разрушении. Имя конструктора совпадает с именем класса. Функция деструктора имеет имя совпадающее с именем класса, но ему предшествует символ тильда (~). Следующий пример создаёт точку на плоскости с координатами по умолчанию (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". |
Нет комментариев. Оставить комментарий: |