В Object Pascal все объекты создаются в куче памяти, а не в стеке, поэтому конструктор не будет автоматически вызываться компилятором, как в C++. Создание объектов и разрушение объектов является обязанностью программиста.
Чтобы создать объект, вы должны сначала выделить для него память. Этот шаг поддерживается компилятором Object Pascal — так называемая «Магия компилятора». Magic)", программисту не обязательно участвовать в этом процессе; тогда члены данных объекта должны быть инициализированы, а за их "очистку" будет отвечать компилятор, но при наличии специального назначения его можно выполнить в конструкторе; при уничтожении объекта необходимо освободить запрошенные ресурсы (а не память, занимаемую самим объектом). За эти задачи отвечает деструктор, который также выполняет переработку памяти, занятой самим объектом; «Магия компилятора».
Выделение и переработка объектной памяти
Когда компилятор выделяет память для объекта, он обеспечивает поддержку, заключающуюся в вставке этих строк ассемблерного кода перед вызовом конструктора:
тест дл, дл
jz +$08
добавить особенно, -$10
вызов @ClassCreate // Обратите внимание на эту строку кода
Последняя строка приведенного выше кода вызывает функцию _ClassCreate в строке 8949 файла system.pas (в зависимости от Delphi 6). Эта функция специально выделяет соответствующую память для каждого объекта. После завершения выделения памяти вызывается конструктор класса для инициализации членов данных. После этого компилятор вставит следующие строки ассемблерного кода:
тест дл, дл
jz +$0f
позвоните @AfterConstruction
pop dWord ptr fs:[$00000000]
добавить esp, $0c
Основная задача — вызвать AfterConstruction каждого экземпляра объекта. Этот вызов бесполезен в Delphi. Его существование зарезервировано для C++Builder.
Аналогично, при разрушении объекта сначала необходимо вызвать деструктор класса, чтобы освободить ресурсы, запрошенные объектом. После этого пространство памяти, занимаемое самим объектом, перерабатывается. Завершает эту работу компилятор, вставив после вызова деструктора следующий ассемблерный код:
позвони @BeforeDestruction
тест дл, дл
jle +$05
позвони @ClassDestroy
Работа, выполняемая этими кодами, соответствует тому, что делается при построении объекта и выделении памяти, главным образом при вызове функции _ClassDestroy в строке 8997 в system.pas.
Конструктор и деструктор
Чтобы определить конструктор, используйте ключевое слово Constructor. По соглашению имя конструктора — Create (конечно, можно использовать и другие имена, но это ни в коем случае не является хорошим дизайном!). нравиться:
тип
TMyFamily = class // Класс, определенный для вашей семьи.
Частный
FMyFatherName : String // имя вашего отца;
FMyMotherName : String // имя вашей матери;
… // Другие члены вашей семьи
Общественный
Конструктор Create(strFatherName, strMotherName: String);
…… // Другие методы
Конец;
Вы можете спросить: если я не предоставлю конструктор для своего класса, можно ли создать его объекты? Ответ: да. Причина была упомянута ранее: выделение памяти, занимаемой самим объектом, завершается компилятором. А поскольку в Object Pascal все классы (кроме самого класса TObject) являются производными от класса TObject, компилятор вызовет конструктор TObject.Create(), но эта функция является пустой функцией и на класс TMyFamily она не повлияет. . Когда элементы данных (FMyFatherName, FMyMotherName) инициализируются, они автоматически очищаются до пустых строк (т. е. ''), поскольку TObject.Create() вообще не знает вашего отца или матери!
При создании объекта конструктор вызывается напрямую, в следующем виде:
MyFamilyObject := TMyFamily.Create('Чжан', 'Ли');
Используйте ключевое слово Destructor для определения деструктора. По соглашению деструктор называется Destroy. нравиться:
тип
ТМиКласс = класс
Общественный
Переопределение деструктора Destroy();
Конец;
Причина, по которой оператор переопределения добавляется в конец объявления деструктора, заключается в том, чтобы гарантировать, что объект может быть правильно разрушен в случае полиморфизма (полиморфизм будет подробно обсуждаться в разделе 2.4). Если вы не добавите ключевое слово override, компилятор выдаст предупреждение, похожее на «Метод 'Destroy' скрывает виртуальный метод базового типа 'TObject'». Предупреждение означает, что определенный вами Destroy скрывает виртуальный метод TObject.Destroy() базового класса. В этом случае объект не может быть правильно уничтожен в полиморфных ситуациях.
Примечание. Деструкторы необходимо объявлять с помощью оператора переопределения.
Аналогично, если в вашем классе нет специальных ресурсов, которые необходимо освободить, вам не нужно определять деструктор. Однако при разрушении объекта следует вызывать метод Free() объекта вместо прямого вызова Destroy().
МойСемейныйОбъект.Свободно();
Это связано с тем, что метод Free() определит, является ли сам объект нулевым, а если он не равен нулю, для повышения безопасности будет вызван метод Destroy() объекта. Теперь, когда есть более безопасные способы сделать это, определенно нет причин не делать этого.
Примечание. Никогда не вызывайте Destroy() непосредственно для объекта, а вместо этого вызывайте Free().
Из этого можно сделать вывод, что в Object Pascal вам нужно уделять внимание только выделению и освобождению запрашиваемых объектом ресурсов, и не нужно заботиться о пространстве, занимаемом самим объектом!