powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Если в конструкторе произойдет исключение, то вызывается деструктор?
25 сообщений из 71, страница 2 из 3
Если в конструкторе произойдет исключение, то вызывается деструктор?
    #39795999
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-CiteЧто должно происходить в конструкторе класса чтобы он упал по ошибке, причем допустимой? Максимум что приходит в голову, только EOutOfMemory и EExternal какие-нибудь..
При проектировании класса вам надо позаботится о том, чтобы в конструкторе не смогли бы быть вызваны не ожидаемые исключения.
авторAnything that can go wrong will go wrong
когда прога идёт на миллионы запусков, случаются даже самые странные вещи, и очень часто неправильно написанный конструктор\деструктор маскирует проблему.

причём, в 10-ке выглядит это очень странно
Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
  procedure CreateComponent;
  var
    ComponentClass: TComponentClass;
  begin
    try
      ComponentClass := FindComponentClass(CompClass);
      Result := nil;
      if Assigned(FOnCreateComponent) then
        FOnCreateComponent(Self, ComponentClass, Result);
      if Result = nil then
      begin
        Result := TComponent(ComponentClass.NewInstance);
        if ffInline in Flags then
        begin
          Include(Result.FComponentState, csLoading);
          Include(Result.FComponentState, csInline);
        end;
        try
          Result.Create(Owner);
        except
          Result := nil;
          raise;
        end;
      end;
      Include(Result.FComponentState, csLoading);
    except
      if not Recover(Result) then raise;
    end;
  end;


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

исходник на паскале не соответствует ассемблерной вставке

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
function _ClassCreate(InstanceOrVMT: Pointer; Alloc: ShortInt): Pointer;
{$IF defined(PUREPASCAL)}
begin
  if Alloc >= 0 then
    InstanceOrVMT := Pointer(TClass(InstanceOrVMT).NewInstance);
  Result := TObject(InstanceOrVMT);
end;
{$ELSE !PUREPASCAL}
{$IFDEF CPUX86}
asm
        { ->    EAX = pointer to VMT      }
        { <-    EAX = pointer to instance }
        PUSH    EDX
        PUSH    ECX
        PUSH    EBX
        TEST    DL,DL
        JL      @@noAlloc
        CALL    DWORD PTR [EAX] + VMTOFFSET TObject.NewInstance
@@noAlloc:
{$IFDEF STACK_BASED_EXCEPTIONS}
        XOR     EDX,EDX
        LEA     ECX,[ESP+16]
        MOV     EBX,FS:[EDX]
        MOV     [ECX].TExcFrame.next,EBX
        MOV     [ECX].TExcFrame.hEBP,EBP
        MOV     [ECX].TExcFrame.desc,offset @desc
        MOV     [ECX].TexcFrame.ConstructedObject,EAX   { trick: remember copy to instance }
        MOV     FS:[EDX],ECX
{$ENDIF STACK_BASED_EXCEPTIONS}
        POP     EBX
        POP     ECX
        POP     EDX
        RET

{$IFDEF STACK_BASED_EXCEPTIONS}
@desc:
        JMP     _HandleAnyException

  {       destroy the object                                                      }

        MOV     EAX,[ESP+8+9*4]
        MOV     EAX,[EAX].TExcFrame.ConstructedObject
        TEST    EAX,EAX
        JE      @@skip
        MOV     ECX,[EAX]
        MOV     DL,$81
        PUSH    EAX
        CALL    DWORD PTR [ECX] + VMTOFFSET TObject.Destroy
        POP     EAX
        CALL    _ClassDestroy
@@skip:
  {       reraise the exception   }
        CALL    _RaiseAgain
{$ENDIF STACK_BASED_EXCEPTIONS}
end;
{$ENDIF CPUX86}
{$ENDIF !PUREPASCAL}

...
Рейтинг: 0 / 0
Если в конструкторе произойдет исключение, то вызывается деструктор?
    #39796027
Фотография Gator
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kealon(Ruslan)вызов конструктора как метод не должен удалять объект Подумай! Как удалить то, чего нет!
Вот ты из лего строишь дом. Вдруг пёс налетел и сборку развалил и погрыз. Лего больше нет. И дом не вышел. Осталось осколки веником подмести и отнести на помойку.
С песчаными замками тоже. Строишь-строишь, а тут цунами.
...
Рейтинг: 0 / 0
Если в конструкторе произойдет исключение, то вызывается деструктор?
    #39796028
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
krapotkinну и вызывать Destroy вообще говоря неверно
нужно Free
а лучше FreeAndNilИногда возможна неприятная ситуация.
FreeAndNil вначале обnilяет ссылку, а затем вызывает Free (не представляю, зачем так сделали). И если где-то в недрах деструктора использовалась эта ссылка (как глобальная переменная, к примеру), то будет плохо.
Понятно, что к такому может привести только говнокод, но такое случается.
...
Рейтинг: 0 / 0
Если в конструкторе произойдет исключение, то вызывается деструктор?
    #39796029
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Kazantsev AlexeyX-Cite,

А в параметризированных конструкторах?

Assert для этого. Проектировать классы надо так, чтобы конструкторы не падали по ожидаемой ошибке во время выполнения.
...
Рейтинг: 0 / 0
Если в конструкторе произойдет исключение, то вызывается деструктор?
    #39796032
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-CiteAssert для этого.
Это тоже будет исключением.
X-CiteПроектировать классы надо так, чтобы конструкторы не падали по ожидаемой ошибке во время выполнения.
Глупости. Как ты сможешь гарантировать, что, например, конструктор TFileStream не грохнется от тысячи и одной причины?
...
Рейтинг: 0 / 0
Если в конструкторе произойдет исключение, то вызывается деструктор?
    #39796036
Valery_B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-CiteЧто должно происходить в конструкторе класса чтобы он упал по ошибке, причем допустимой? Максимум что приходит в голову, только EOutOfMemory и EExternal какие-нибудь..

Исключения в конструкторах - нормальное явление, хоть и не желательное.
Попробуй TFileStream.Create
...
Рейтинг: 0 / 0
Если в конструкторе произойдет исключение, то вызывается деструктор?
    #39796037
Valery_B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Movie #30 - Exceptions in Constructors and Desctructors

YouTube Video
...
Рейтинг: 0 / 0
Если в конструкторе произойдет исключение, то вызывается деструктор?
    #39796055
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
TFileStream как раз таки генерирует исключение связанное с внешним ресурсом, в моей нотации это External
Мы же говорим о замкнутой системе классов, проектируемой в рамках библиотеки/фреймворка/прилоежния.
При проектировании таких классов, можно легко избежать возбуждения исключений не связанных с памятью, и внешними ресурсами..
...
Рейтинг: 0 / 0
Если в конструкторе произойдет исключение, то вызывается деструктор?
    #39796057
Kazantsev Alexey
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-Cite,

Этак всё к external отнести можно, параметры же извне поступают...
...
Рейтинг: 0 / 0
Если в конструкторе произойдет исключение, то вызывается деструктор?
    #39796085
High.Programer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
ziv-2014
Код: pascal
1.
2.
3.
4.
destructor TCheckListBox.Destroy;
begin
  ...
end;


Используйте блоки try except end; или try finally end;
Уважаемый, это был код из VCL . И вы решили авторам VCL указаывать как надо деструкторы писать?
...
Рейтинг: 0 / 0
Если в конструкторе произойдет исключение, то вызывается деструктор?
    #39796090
High.Programer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
X-CiteЧто должно происходить в конструкторе класса чтобы он упал по ошибке ...
Уважаемый, вы задаете странные вопросы.
В конструкторах часто происходит много работы по инициализации объектов, выделение рерурсов/памяти, цепочка вызовов конструкторов агрегированных объектов, вызовы родительских конструкторов ... и т.д. и т.п.

А вы привыкли, работать с "пустыми" конструкорами?
...
Рейтинг: 0 / 0
Если в конструкторе произойдет исключение, то вызывается деструктор?
    #39796127
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
High.Programer,

Никто не спорит что там это все происходит..

авторТ.е. на этапе разработки такие проблемы исключаются.

Когда что-то уходит в релиз, там уже нечему вызывать исключения.. Теоретически оно может, а практически никогда. А если там развалилось что-то связанное с памятью это уже и так фатал.

А если класс нарушает принцип единственной ответственности, ну так это уже проблемы другого уровня.
...
Рейтинг: 0 / 0
Если в конструкторе произойдет исключение, то вызывается деструктор?
    #39796155
Valery_B
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
X-CiteА если класс нарушает принцип единственной ответственности, ну так это уже проблемы другого уровня.

В принципе - да.
И если я тебя правильно понял, то raise Exception.Create в конструкторах быть не должно(т.е. предвиденное исключение).
TFileStream - это исключение, а не правило.
High.ProgramerА вы привыкли, работать с "пустыми" конструкорами?

Я да. Так или иначе 99% конструкторов это:
1. Наследник от TForm
2. Наследник от TControl
3. Наследник от TObject.

А если в проекте, есть какой-то другой базовый класс, от которого надо наследоваться и в нём вылезает исключение - то это проблема автора базового класса.
...
Рейтинг: 0 / 0
Если в конструкторе произойдет исключение, то вызывается деструктор?
    #39796157
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Gatorkealon(Ruslan)вызов конструктора как метод не должен удалять объект Подумай! Как удалить то, чего нет!
Вот ты из лего строишь дом. Вдруг пёс налетел и сборку развалил и погрыз. Лего больше нет. И дом не вышел. Осталось осколки веником подмести и отнести на помойку.
С песчаными замками тоже. Строишь-строишь, а тут цунами.если следовать такой аналогии
вот ты дом сразу без фундамента строишь? нет, сначала нужно выделить память под объект, а потом уже вызывать его постройку

Не получилось у бригады дом построить и они тебе всё снесли вместе с фундаментом, круто?
Вот и тут так же, т.е. если я напрямую вызываю метод объекта я не ожидаю, что он вызовет удаление памяти под него. Кто выделял память тот и должен удалять,
...
Рейтинг: 0 / 0
Если в конструкторе произойдет исключение, то вызывается деструктор?
    #39796310
High.Programer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Valery_BHigh.ProgramerА вы привыкли, работать с "пустыми" конструкорами?

Я да. Так или иначе 99% конструкторов это:
1. Наследник от TForm

Уважаемый, Вы напрасно испытываете мое терпение, т.к. у TForm самый "проблемный" конструктуор из всей VCL. А вы думали он "пустой" ?

Код: pascal
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
constructor TCustomForm.Create(AOwner: TComponent);
begin
  GlobalNameSpace.BeginWrite;
  try
    CreateNew(AOwner);
    if (ClassType <> TForm) and not (csDesigning in ComponentState) then
    begin
      Include(FFormState, fsCreating);
      try
        if not InitInheritedComponent(Self, TForm) then
          raise EResNotFound.CreateFmt(SResNotFound, [ClassName]);
      finally
        Exclude(FFormState, fsCreating);
      end;
      if OldCreateOrder then DoCreate;
    end;
  finally
    GlobalNameSpace.EndWrite;
  end;
end;


... а внутрь CreateNew(AOwner) даже не заглядывайте, там Вас ждет ужасное разочарование в виде нескончаемых выделений ресурсов операционной системы (в вашем случае MS Windows)

Вы все еще мечтаете о "пустых" конструкторах?
...
Рейтинг: 0 / 0
Если в конструкторе произойдет исключение, то вызывается деструктор?
    #39796332
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockFreeAndNil вначале обnilяет ссылку, а затем вызывает Free (не представляю, зачем так сделали). И если где-то в недрах деструктора использовалась эта ссылка (как глобальная переменная, к примеру), то будет плохо.
Понятно, что к такому может привести только говнокод, но такое случается.
Если кто-то в деструкторе объекта использует внешнюю ссылку на экземпляр этого же объекта, то я даже не знаю как такого человека вежливо назвать...
...
Рейтинг: 0 / 0
Если в конструкторе произойдет исключение, то вызывается деструктор?
    #39796335
alekcvp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockFreeAndNil вначале обnilяет ссылку, а затем вызывает Free (не представляю, зачем так сделали).И, кстати, сделали это чтобы после вызова FreeAndNil можно было быть на 100% уверенным, что ссылка будет обнулена, даже если в деструкторе объекта возникнет исключение.
...
Рейтинг: 0 / 0
Если в конструкторе произойдет исключение, то вызывается деструктор?
    #39796461
vavan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
High.ProgramerВ конструкторах часто происходит много работы по инициализации объектов, выделение рерурсов/памяти, цепочка вызовов конструкторов агрегированных объектов, вызовы родительских конструкторов ... и т.д. и т.п.а в деструкторах соответственно часто все должно разматываться в обратную сторону и сюрпризом для кого-то могут оказаться деструкторы таки вызывающие исключения и порой именно в продуктиве
...
Рейтинг: 0 / 0
Если в конструкторе произойдет исключение, то вызывается деструктор?
    #39796871
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
alekcvpYuRockFreeAndNil вначале обnilяет ссылку, а затем вызывает Free (не представляю, зачем так сделали).И, кстати, сделали это чтобы после вызова FreeAndNil можно было быть на 100% уверенным, что ссылка будет обнулена, даже если в деструкторе объекта возникнет исключение.А, теперь понятно. Но тогда логичнее было назвать функцию NilAndFree. Я как-то из-за такой проблемы долго бился.

P.S. Я лишь привел пример случая, когда o.Free; o := nil; гораздо надежнее, чем FreeAndNil. Особенно, когда работаешь с громадной базой кода, зачастую - чужого.
Та же дельфя побуждает глобальные переменные типа Form1 юзать. Вот и юзают, даже внутри методов формы.
А бывает, и сам не заметишь, как что-то подобное сам замутишь. В моем случае использовалась ссылка (на себя) из объекта-owner'а, через три прослойки заюзанная в деструкторе.
Хорошо, конечно, что я в итоге упростил и улучшил этот говнокод. Но не напиши я там FreeAndNil тогда - не потратил бы день и по сейчас не знал бы об этой проблеме.
...
Рейтинг: 0 / 0
Если в конструкторе произойдет исключение, то вызывается деструктор?
    #39796876
Vlad F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Однако, парни, надо исходить из того, что в конструкторах, в общем случае, независимо от всех ваших заклинаний,
может произойти все, что угодно. И, исходя именно из этой простой мысли, надо отдавать себе отчет, как же имено
предохраняться деструкторах.
...
Рейтинг: 0 / 0
Если в конструкторе произойдет исключение, то вызывается деструктор?
    #39796879
YuRock
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vlad FОднако, парни, надо исходить из того, что в конструкторах, в общем случае, независимо от всех ваших заклинаний,
может произойти все, что угодно. И, исходя именно из этой простой мысли, надо отдавать себе отчет, как же имено
предохраняться деструкторах.Понятно, что надо. И это прямым текстом написано в хелпе (как-то читал).
Только ничего сложного в этом нет. Есть Free и есть if Assigned для более сложных редких случаев.
...
Рейтинг: 0 / 0
Если в конструкторе произойдет исключение, то вызывается деструктор?
    #39797001
vavan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Vlad Fнадо исходить из того, что в конструкторах, в общем случае, независимо от всех ваших заклинаний,
может произойти все, что угоднои в деструкторах, причем чужих
...
Рейтинг: 0 / 0
Если в конструкторе произойдет исключение, то вызывается деструктор?
    #39797002
Фотография makhaon
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRock,

авторХорошо, конечно, что я в итоге упростил и улучшил этот говнокод. Но не напиши я там FreeAndNil тогда - не потратил бы день и по сейчас не знал бы об этой проблеме.
Не понял, при чем здесь FreeAndNil? Ну юзал бы ты Free вместо FreeAndNil стало бы легче? Всё равно бы полез к разрушенной ссылке. Только в случае FreeAndNil тебе сразу по пальцам дали. А в случае Free имел бы вяло-текущий и проявляющийся в одном случае из десяти или ста баг. Который бы искал не день, а неделю.
...
Рейтинг: 0 / 0
Если в конструкторе произойдет исключение, то вызывается деструктор?
    #39797004
vavan
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
YuRockэто прямым текстом написано в хелпесобсно для использования в деструкторах и был изобретен free, для ряда прочих случаев можно сразу дестроить
...
Рейтинг: 0 / 0
Если в конструкторе произойдет исключение, то вызывается деструктор?
    #39797057
kealon(Ruslan)
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ну вы фантазёры

сначала был изобретён метод free, как раз для деструкторов, что бы если объект не инициализировался в конструкторе при исключении можно было писать код без проверки существования объекта

потом поняли, что ссылка на убитый объект - лажа, и писать отдельно код для её обнуления не камильфо, и придумали FreeAndNil
...
Рейтинг: 0 / 0
25 сообщений из 71, страница 2 из 3
Форумы / Delphi [игнор отключен] [закрыт для гостей] / Если в конструкторе произойдет исключение, то вызывается деструктор?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]