2016-09-17 3 views
1

Я уже нашел что-то в stackoverflow, но это действительно не решает моих сомнений. Я знаю, что правильный способ создания объекта после создания окружает код в блоке try-finally. Но как насчет:Конструктор Delphi TForm

procedure TForm3.FormCreate(Sender: TObject); 
begin 
    a := TClassX.Create; 
end; 

, а затем вызвать:

procedure TForm3.FormDestroy(Sender: TObject); 
begin 
    a.Free; 
end; 

Где a: TClassX; является публичным заявлением внутри TForm3 класса. Должен ли я создать конструктор и деструктор для формы, или я могу использовать код выше? Это безопасно?

+0

Если класс поддерживает владельцев (является потомком TControl или является TComponent?), То вы также можете использовать * a: = TClassX.Create (Self) * и позволить деструктору вашей формы освободить экземпляр «a» , Вам тогда не нужно будет беспокоиться о части a.Free (это будет сделано деструктором TForm). – HeartWare

+1

Я бы рекомендовал вам ** не ** объявлять 'a: TClassX' в общедоступном разделе. Он предотвращает инкапсуляцию, и по мере увеличения базы кода общее приложение становится более сложным. И будет более сложно уверенно рассуждать о правильности вашего кода. –

ответ

8

Попытка /, наконец, есть или, по крайней мере, что-то эквивалентное. Он просто существует вне вашего кода, выше стека вызовов. Что-то вроде:

Form1 := TForm1.Create(nil); 
try 
    // do stuff 
finally 
    Form1.Free; 
end; 

Вашего OnCreate и OnDestroy обработчиков вызывается из конструктора и деструктора, соответственно, и таким образом защищены.

Пока все играют по правилам, ничего не течет. И здесь правила - это объекты, созданные в конструкторе и подлежащие уничтожению в деструкторе. Тот, кто на самом деле создает объект, несет ответственность за то, чтобы он был уничтожен, несмотря ни на что. Но это задача потребителя вашего класса, а не вас.

0

У меня были некоторые проблемы с этими событиями некоторое время назад, поэтому я бы не рекомендовал использовать OnCreate/OnDestroy событий в вашем приложении. Вот только некоторые случаи, которые я помню:

  • VCL по умолчанию обрабатывает исключение из OnCreate/OnDestroy событий. Фактически, если a:=TClassX.Create; генерирует исключение, оно будет показано обработчиком исключений приложения, но форма будет создана успешно, сохраняя переменную «a» равной нулю. Это может привести к нарушениям доступа, если вы попытаетесь получить доступ к этой переменной позже.

  • В зависимости от OldCreateOrder этих событий может быть вызван либо из конструктора/деструктора или AfterConstruction/BeforeDestruction методами. Это может также привести к нарушению доступа, если вы время от времени изменять OldCreateOrder в виде потомков

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

Смежные вопросы