Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Конструкторы, перегрузка конструкторов



В объектно-ориентированном программировании конструктор класса (от англ. constructor, иногда сокращают ctor ) — специальный блок инструкций, вызываемый при создании объекта.

Конструктор схож с методом, но отличается от метода тем, что не имеет явным образом определённого типа возвращаемых данных, не наследуется, и обычно имеет различные правила для рассматриваемых модификаторов. Конструкторы часто выделяются наличием одинакового имени с именем класса, в котором объявляется. Их задача — инициализировать члены объекта и определить инвариант класса, сообщив в случае некорректности инварианта. Корректно написанный конструктор оставитобъект в «правильном» состоянии. Неизменяемые объекты тоже должны быть проинициализированы конструктором.

Термин «конструктор» также используется для обозначения одного из тегов, описывающих данные в алгебраическом типе данных. Это использование несколько отличается от описываемого в статье. Для дополнительной информации смотрите Алгебраический тип данных.

В большинстве языков конструктор может быть перегружен, что позволяет использовать несколько конструкторов в одном классе, причём каждый конструктор может иметь различные параметры.

Одна из ключевых особенностей ООП — инкапсуляция: внутренние поля объекта напрямую недоступны, и пользователь может работать с объектом только как с единым целым, через открытые (public) методы. Каждый метод, в идеале, должен быть устроен так, чтобы объект, находящийся в «допустимом» состоянии (то есть когда выполняется инвариант класса), после вызова метода также оказался в допустимом состоянии. И первая задача конструктора — перевести поля объекта в такое состояние.

Вторая задача — упростить пользование объектом. Объект — не «вещь в себе», ему часто приходится требовать какую-то информацию от других объектов: например, объект File, создаваясь, должен получить имя файла. Это можно сделать и через метод:

File file; file.open(" in.txt", File:: omRead);

Но удобнее открытие файла сделать в конструкторе:

File file(" in.txt", File:: omRead);

Некоторые языки программирования различают несколько особых типов конструкторов:

конструктор по умолчанию — конструктор, не принимающий аргументов;

конструктор копирования — конструктор, принимающий в качестве аргумента объект того же класса (или ссылку из него);

конструктор преобразования — конструктор, принимающий один аргумент (эти конструкторы могут вызываться автоматически для преобразования значений других типов в объекты данного класса).

class Complex{ public: // Конструктор по умолчанию // (в данном случае является также и конструктором преобразования) Complex(double i_re = 0, double i_im = 0): re(i_re), im(i_im) {} // Конструктор копирования Complex(const Complex & obj) { re = obj.re; im = obj.im; } private: double re, im; };

Конструктор по умолчанию

Основная статья: Конструктор по умолчанию

Конструктор не имеющий обязательных аргументов. Используется при создании массивов объектов, вызываясь для создания каждого экземпляра. В отсутствие явно заданного конструктора по умолчанию его код генерируется компилятором (что на исходном тексте, естественно, не отражается).

[править]Конструктор копирования

Основная статья: Конструктор копирования

Конструктор, аргументом которого является ссылка на объект того же класса. Применяется в C++ для передачи объектов в функции по значению.

Конструктор копирования в основном необходим, когда объект имеет указатели на объекты, выделенные в куче. Если программист не создаёт конструктор копирования, то компилятор создаст неявный конструктор копирования, который копирует указатели как есть, то есть фактическое копирование данных не происходит и два объекта ссылаются на одни и те же данные в куче. Соответственно попытка изменения «копии» повредит оригинал, а вызов деструктора для одного из этих объектов при последующем использовании другого приведёт к обращению в область памяти, уже не принадлежащую программе.

Аргумент должен передаваться именно по ссылке, а не по значению. Это вытекает из коллизии: при передаче объекта по значению (в частности, для вызова конструктора) требуется скопировать объект. Но для того, чтобы скопировать объект, необходимо вызвать конструктор копирования.

[править]Конструктор преобразования

Конструктор, принимающий один аргумент. Задаёт преобразование типа своего аргумента в тип конструктора. Такое преобразование типа неявно применяется только если оно уникально.

[править]Виртуальный конструктор

Конструктор не бывает виртуальным в смысле виртуального метода — для того, чтобы механизм виртуальных методов работал, нужно запустить конструктор, который автоматически настроит таблицу виртуальных методов данного объекта.

«Виртуальными конструкторами» называют похожий, но другой механизм, присутствующий в некоторых языках — например, он есть в Delphi, но нет в C++ и Java. Этот механизм позволяет создать объект любого заранее неизвестного класса при двух условиях:

· этот класс является потомком некоего наперёд заданного класса (в данном примере это класс TVehicle);

· на всём пути наследования от базового класса к создаваемому цепочка переопределения не обрывалась. При переопределении виртуального метода синтаксис Delphi требует ключевое слово overload, чтобы старая и новая функции с разными сигнатурами могли сосуществовать, override для переопределения функции либо reintroduce для задания новой функции с тем же именем — последнее недопустимо.

Синтаксис

Delphi

В Delphi, в отличие от C++, для объявления конструктора служит ключевое слово constructor. Имя конструктора может быть любым, но рекомендуется называть конструктор Create.

[править]Пример

TClassWithConstructor = class public constructor Create; end;

Конструктор перегрузки

Конструкторы, используемые для создания экземпляров объектов, также могут быть перегружены в некоторых объектно-ориентированных языках программирования. Потому что во многих языках название конструктора предопределено именем класса, казалось бы, что может быть только один конструктор. Всякий раз, когда несколько конструкторов нужны, они реализованы в виде перегруженных функций. Конструктор по умолчанию не принимает параметров, экземпляр объекта члены с нулевым значением. [ 1 ] Например, конструктор по умолчанию для объекта bill в ресторане написана на C + + может установить Tip до 15%:

Bill(){ tip = 15.0; total = 0.0; }

Недостатком является то, что он делает два шага, чтобы изменить значение созданного Bill объекта. Ниже показано создание и изменение значений в рамках основной программы:

Bill cafe; cafe.tip = 10.00; cafe.total = 4.00;

По перегрузке конструктора, можно было бы передать чаевые и общем качестве параметров при создании. Это показывает, перегруженный конструктор с двумя параметрами:

Bill(double setTip, double setTotal){ tip = setTip; total = setTotal; }

Теперь функция, которая создает новый объект Bill может иметь два значения в конструктор и устанавливать элементы данных в один шаг. Ниже показано создание и установка значений:

Bill cafe(10.00, 4.00);

Это может быть полезно в повышении эффективности программ и сокращение длины кода.

Деструкторы

Дестру́ ктор — специальный метод класса, служащий для деинициализации объекта (например освобождения памяти).

Деструктор в Delphi

Для объявления деструктора в Delphi используется ключевое слово destructor. Имя деструктора может быть любым, но рекомендуется всегда называть деструкторDestroy.

TClassWithDestructor = class destructor Destroy; override; end;

В Delphi все классы являются потомками, по крайней мере, класса TObject, поэтому, для корректного освобождения памяти, необходимо перекрывать деструктор, используя директиву override.

В Delphi прямой вызов деструктора используется редко. Вместо него используют метод Free.

MyObject.Free;

Метод Free вначале проверяет существует ли уничтожаемый объект, а затем вызывает деструктор. Этот прием позволяет избегать ошибок, возникающих при обращении к несуществующему объекту.


Поделиться:



Популярное:

Последнее изменение этой страницы: 2016-07-14; Просмотров: 856; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.016 с.)
Главная | Случайная страница | Обратная связь