27. Конструкторы и деструкторы.
Конструктор – функция инициализации класса. В момент создания объекта вызывается конструктор класса. Конструктор – функция, в которой инициализируются члены класса и выполняются другие подготовительные действия. Конструктор всегда имеет имя, совпадающее с именем класса, и никогда не может возвращать никакого значения. Можно иметь любое число конструкторов для одного класса до тех пор, пока каэжый из них имеет свой список параметров (сигнатуру). При инициализации объекта выбирается и выполняется конструктор с соответствующим списком параметров. При отсутствии параметров вызывается конструктор класса по умолчанию.
Деструктор – противоположность конструктора. Если конструктор вызывается для создания объекта, то деструктор вызывается для удаления объекта из памяти. Обычно нет необходимости определять деструктор для каждого класса в явном виде, так как он вызывается автоматически (например, при использовании оператора delete). Однако, существуют ситуации, когда необходимо аккуратное уничтожение объекта (например, при закрытии файлов, связанных с объектом). В отличие от конструктора, деструктор может быть только один для всего класса.
Память, выделенная объектам при последнем обращении к ним, освобождается только при выходе из программы, что создаёт значительные трудности, справиться которыми можно с помощью конструкторов и деструкторов. Это специальные функции класса, которые управляют процессом создания и удаления объектов и имеют необычный синтаксис:
- имя конструктора совпадает с именем класса и выглядит как: <имя класса>;
- имя деструктора совпадает с именем класса и выглядит как: ~<имя класса>;
Пример кода программы, содержащей конструктор и деструктор:
class ClassName // имя класса
{
ClassName(); // конструктор
~ClassName(); // деструктор
};
Деструктор освобождает последний выделенный блок памяти.
Конструктор – функция-член класса, которая создаёт объекты данного класса, выделяя для них память и/или инициализируя их.
Для корректного определения класса необходимо иметь несколько конструкторов. Все они имеют одно и то же имя, совпадающее с именем класса, но отличаются числом и типом параметров (например, конструктор копирования – используется для инициализации объекта с помощью другого объекта того же класса).
Каждый класс имеет конструктор по умолчанию (конструктор без параметров), являющийся скрытым и инициализирующий данные-члены нулями. Если для класса определён хотя бы один конструктор, то конструктор по умолчанию исчезает. Таким образом, в определение класса всегда стоит включать конструктор без параметров, даже если он не выполняет никаких операций. После его явного определения он подставляется вместо конструктора по умолчанию и уже не может исчезнуть, даже если будет определён ещё какой-либо конструктор. Конструкторы по умолчанию были введены для совместимости с простейшими классами, которые не могли иметь функций-членов.
28. Перегрузка классов.
Термин “перегрузка” означает повторное использование символа или имени.
Перегрузка операторов: к примеру, можно определить смысл оператора сложения (+) для своего класса, то есть организовать перегрузку оператора (operator overloading). Далеко не всё объектно-ориентированные языки поддерживают данную возможность, хотя, она и не является отличительным свойством ООП. Подобная особенность позволяет переопределить практически любой оператор C++ и приблизить синтаксис языка к синтаксису других, возможно, более привычных для программиста языков.
Для данного оператора “@” имя его функции определяется, как:
operator@
Перегрузка функций – это возможность написать несколько функций с одним и тем же именем.
Во избежание конфликта имён все функции должны иметь уникальные списки параметров (фактически же, имя функции расширяется списком параметров, что снимает конфликт).
Прототипы трёх функций с одним и тем же именем, но инициализирующие различные данные:
void In1t_var(int),
void In1t_var(double),
void In1t_var(char*),
Не смотря на то, что все три функции имеют одинаковые имена, каждая из них совершенно самостоятельна и должна иметь собственное определение. Во время компиляции компилятор анализирует тип параметра, передаваемого в функцию, и выбирает функцию с соответствующим параметром. На перегруженные функции накладываются определённые ограничения. Каждая функция должна иметь уникальную сигнатуру (список параметров), то есть списки параметров должны отличаться по числу и/или типу аргументов. Тип возвращаемого значения функции в понятие сигнатуры не включается, и функции не могут иметь разные возвращаемые типы при одном и том же списке параметров, но если сигнатуры отличаются, то функция может иметь различные типы возвращаемого значения.