2013-06-25 3 views
5

Действительно ли в Delphi нормально выполнять код после унаследованного вызова в деструкторе?Деструкторы Delphi: выполнение кода после унаследованного вызова?

Вы можете найти это в System.Classes:

destructor TThread.Destroy; 
begin 
[...] 
    inherited Destroy; 
    FFatalException.Free; 
end; 

Я думаю, что доступ к члену экземпляра после вызова унаследованного Уничтожьте методом является плохой идеей.

+0

Я бы не подумал, что все в порядке. –

+0

@JerryDodge: На самом деле это может быть очень необходимо. Например, когда вам нужно защитить деструктор от исключений и/или многопоточного исполнения. В этом случае вы почти всегда будете иметь код, который выполняется после унаследованного вызова. Также может потребоваться обеспечить жизнь экземпляров-членов, которые обслуживают обратные вызовы, которые могут быть вызваны из унаследованного деструктора. IOW: для этого может быть много причин, но я согласен с тем, что это действительно очень, очень, очень тщательно. –

+1

Это так же корректно, как и создание вещей перед наследованным вызовом в конструкторе. Не общий, но действительный. Также TThread наследует от TObject, поэтому в этом унаследованном вызове ничего не происходит. –

ответ

7

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

Но это, конечно, правда, что это не хороший стиль. В некоторых случаях есть причины, которые приведут вас к такому коду, но обычно такие причины следует воспринимать как указание на то, что в вашем дизайне что-то не так.

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

4

экземпляр не удаляется из памяти с помощью самого метода деструктора, но по зову TObject.FreeInstance

TObject.FreeInstance называется, так как деструктор вызывается, после обработки коды деструктора.

BTW: То же самое и с конструктором. Экземпляр создается class function TObject.NewInstance : TObject и называется перед тем называется конструктор (только потому, что он является конструктором)

Из-за этого, вы будете иметь действительный экземпляр внутри целого конструктора или деструктора кода.

+0

Даже после того, как экземпляр исчез, вы можете выполнить код, пока не ссылаетесь на экземпляр –

+0

@DavidHeffernan, который является общим для всех методов, но вопрос был о поле класса после унаследованного и эта ссылка на экземпляр; o) –

+0

Это верно для примера. Я был немного более общим в соответствии с * это действительно нормально в Delphi для выполнения кода после унаследованного вызова в деструкторе? * –