Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Почтовая рассылка

Подписчиков: -1
Последний выпуск: 19.06.2015

TForm::Release()

501
27 января 2005 года
hell_admin
110 / / 02.10.2004
Здрасте все,

Такая проблема, я создаю окна и помешаю их в стек

TMyForm * MyForm = new TMyForm(this);
Stack->Push(MyForm);

а при закрытии окна я вызываю Pop(), поскольку у меня все окна перекрывают друг друга, т.е. нельзя переключится между окнами, то при вызове Pop() как раз будет закрыто верхнее окно.

void TMain::Pop()
{
--wCount;
if (wCount < 0 )
{
ShowMessage("?????? ???????? ????");
return;
}
Wins[wCount]->Close();
Wins[wCount]->Release();
Wins[wCount] = NULL;

}
Вот такая функция.
Но на некоторых окнах, при закрити окна уже, после вызова функции Pop() (я пошагово в отдладчике смотрел), получается исключение

---------------------------
Debugger Exception Notification
---------------------------
Project Viewer.exe raised exception class EAccessViolation with message 'Access violation at address 00000000. Read of address 00000000'. Process stopped. Use Step or Run to continue.
---------------------------
OK Help
---------------------------

Что за хрень? если в дебаггере смотреть то он код ассемблера дальше выдает и типа исключение тоже там же, т.е. не поймеш в какой строчке кода эта хрень произошла.
За границы массива на котором реализован Стек я не выхожу.
246
27 января 2005 года
GIZMO
1.8K / / 30.07.2004
Цитата:
Originally posted by hell_admin
Здрасте все,

Такая проблема, я создаю окна и помешаю их в стек

TMyForm * MyForm = new TMyForm(this);
Stack->Push(MyForm);

а при закрытии окна я вызываю Pop(), поскольку у меня все окна перекрывают друг друга, т.е. нельзя переключится между окнами, то при вызове Pop() как раз будет закрыто верхнее окно.

void TMain::Pop()
{
--wCount;
if (wCount < 0 )
{
ShowMessage("?????? ???????? ????");
return;
}
Wins[wCount]->Close();
Wins[wCount]->Release();
Wins[wCount] = NULL;

}
Вот такая функция.
Но на некоторых окнах, при закрити окна уже, после вызова функции Pop() (я пошагово в отдладчике смотрел), получается исключение

---------------------------
Debugger Exception Notification
---------------------------
Project Viewer.exe raised exception class EAccessViolation with message 'Access violation at address 00000000. Read of address 00000000'. Process stopped. Use Step or Run to continue.
---------------------------
OK Help
---------------------------

Что за хрень? если в дебаггере смотреть то он код ассемблера дальше выдает и типа исключение тоже там же, т.е. не поймеш в какой строчке кода эта хрень произошла.
За границы массива на котором реализован Стек я не выхожу.


В BCB только delete Wins[wCount] и никаких Free() и Release()

1
27 января 2005 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by GIZMO

В BCB только delete Wins[wCount] и никаких Free() и Release()


Здесь даже проблема не столько в BCB - ведь для создания формы ты используешь new. Если я верно с этим разобрался Страуструп специально ввел операторы new и delete, что бы гарантировать при инициализации вызов конструктора, а соответственно при разрушении - деструктора. для функций типа Release() это никто не гарантировал. Это первое. Второе - сто в гору - деструктор ты для формы не определял - значит должен отработать деструктор базового класса. Он это и пытается сделать - но объект уже разрушен...

259
28 января 2005 года
AlexandrVSmirno
1.4K / / 03.12.2004
Цитата:
Originally posted by hell_admin
Здрасте все,

Такая проблема, я создаю окна и помешаю их в стек

TMyForm * MyForm = new TMyForm(this);
Stack->Push(MyForm);

а при закрытии окна я вызываю Pop(), поскольку у меня все окна перекрывают друг друга, т.е. нельзя переключится между окнами, то при вызове Pop() как раз будет закрыто верхнее окно.

void TMain::Pop()
{
--wCount;
if (wCount < 0 )
{
ShowMessage("?????? ???????? ????");
return;
}
Wins[wCount]->Close();
Wins[wCount]->Release();
Wins[wCount] = NULL;

}
Вот такая функция.
Но на некоторых окнах, при закрити окна уже, после вызова функции Pop() (я пошагово в отдладчике смотрел), получается исключение

---------------------------
Debugger Exception Notification
---------------------------
Project Viewer.exe raised exception class EAccessViolation with message 'Access violation at address 00000000. Read of address 00000000'. Process stopped. Use Step or Run to continue.
---------------------------
OK Help
---------------------------

Что за хрень? если в дебаггере смотреть то он код ассемблера дальше выдает и типа исключение тоже там же, т.е. не поймеш в какой строчке кода эта хрень произошла.
За границы массива на котором реализован Стек я не выхожу.


Окна уже в методе Close могут себя удалять. Поэтому Release делать не обязательно. Прваильней делать так:

 
Код:
Wins[wCount]->Close();
  if(Wins[wCount])
  {
      Wins[wCount]->Release();
      Wins[wCount] = NULL;
  }
501
28 января 2005 года
hell_admin
110 / / 02.10.2004
Цитата:


В BCB только delete Wins[wCount] и никаких Free() и Release()



Все дело в том что если написать:

TMyForm * f = new TMyform(this);
f->ShowModal();
delete f;


то как раз на третьей строчке и вылетит исключение, поэтому я посмотрел в help'e BCB на тему деструктора TForm:

Frees the memory associated with the TForm object.

__fastcall virtual ~TForm(void) { }

Description

Do not explicitly destroy form objects. Instead, use the Release method to free a form. Release waits until all event handlers have finished executing before destroying the form.

Т.е. как я понял delete нельзя вызывать, а надо Release.

Цитата:


Окна уже в методе Close могут себя удалять. Поэтому Release делать не обязательно.



Методом научного тыка выяснилось следующее:
Все работает если форму вызывать не ShowModal()
а Show(), и в обработке OnClose() делать
Pop().

Хотелось бы разобратся все таки, как правильно удалять формы и почему в одном случае работает а в другом нет?

1
28 января 2005 года
kot_
7.3K / / 20.01.2000
Вот пример реально работающей программы в которой происходит удаление:
 
Код:
int AddNewTask()
 {
  fmAddOrEditEx = new TfmAddOrEditEx(Application);
  fmAddOrEditEx->ShowModal();
  delete fmAddOrEditEx;
 }

Ни каких проблем не возникает. В примерах билдера есть пример обработки события OnClose:
 
Код:
Action = caFree;

в таком случае удаление делать уже не нужно.
368
28 января 2005 года
rostyslav
629 / / 13.07.2004
Цитата:
Originally posted by hell_admin

Хотелось бы разобратся все таки, как правильно удалять формы и почему в одном случае работает а в другом нет?

В обработчике OnClose формы есть параметр Action = caFree/caHide/caNone/caMinimize.

По умолчанию, она разная, для разных типов форм.

259
28 января 2005 года
AlexandrVSmirno
1.4K / / 03.12.2004
Цитата:
Originally posted by hell_admin


Все дело в том что если написать:

TMyForm * f = new TMyform(this);
f->ShowModal();
delete f;


то как раз на третьей строчке и вылетит исключение, поэтому я посмотрел в help'e BCB на тему деструктора TForm:

Frees the memory associated with the TForm object.

__fastcall virtual ~TForm(void) { }

Description

Do not explicitly destroy form objects. Instead, use the Release method to free a form. Release waits until all event handlers have finished executing before destroying the form.

Т.е. как я понял delete нельзя вызывать, а надо Release.



Методом научного тыка выяснилось следующее:
Все работает если форму вызывать не ShowModal()
а Show(), и в обработке OnClose() делать
Pop().

Хотелось бы разобратся все таки, как правильно удалять формы и почему в одном случае работает а в другом нет?


Модальные формы по своей природе не предпологают свое дальнейшее использование после закрытия, поэтому по методу клозе они и делают еще и релизе

1
28 января 2005 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by AlexandrVSmirno

Модальные формы по своей природе не предпологают свое дальнейшее использование после закрытия, поэтому по методу клозе они и делают еще и релизе


Откуда информация? т.е. код, приведенный ниже недопустим?

 
Код:
...
if(fmModal->ShowModal()==mrOk){
...
int W = fmModal->MyProp;
...
}
delete fmModal;

Ты чтото перепутал.
259
28 января 2005 года
AlexandrVSmirno
1.4K / / 03.12.2004
Цитата:
Originally posted by kot_

Откуда информация? т.е. код, приведенный ниже недопустим?
 
Код:
...
if(fmModal->ShowModal()==mrOk){
...
int W = fmModal->MyProp;
...
}
delete fmModal;

Ты чтото перепутал.


Допустим, если fmModal создавалась как Application->CreateForm(...)

1
28 января 2005 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by AlexandrVSmirno

Допустим, если fmModal создавалась как Application->CreateForm(...)


Ну и что - не важно как она создавалась - важно как отображается....:D
При закрытии модальной формы ее разрушения не происходит в событии OnClose, как впрочем и любой другой, если не вызван оператор delete или свойство Action не было установлено в caFree. Или если не разрушен владелец данной формы.

259
28 января 2005 года
AlexandrVSmirno
1.4K / / 03.12.2004
Цитата:
Originally posted by kot_

Ну и что - не важно как она создавалась - важно как отображается....:D
При закрытии модальной формы ее разрушения не происходит в событии OnClose, как впрочем и любой другой, если не вызван оператор delete или свойство Action не было установлено в caFree. Или если не разрушен владелец данной формы.


Во - во владелец. В VCL именно владелец отвечает за дестрой. А если ты сдлеал new и владелец у тебя NULL, то за delete отвечает сама форма и по close она себя уберет.

1
28 января 2005 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by AlexandrVSmirno

Во - во владелец. В VCL именно владелец отвечает за дестрой. А если ты сдлеал new и владелец у тебя NULL, то за delete отвечает сама форма и по close она себя уберет.


Александр, богатая фантазия - дело хорошее, но первым был барон, который сам себя за волосы из болота вытащил...:) Если владелец явно не указан - то это приложение. И форма будет разрушена только по завершении работы приложения...

501
28 января 2005 года
hell_admin
110 / / 02.10.2004
Спасиба, буду переваривать информацию.
А где можно об этом всем почитать, а то во всех книжках по билдеру которые мне попадались, только и описывается, как создавать нотепады да калькуляторы... а сам механизм ни где не описывается.Все на уровне нажмите туда получите то.
1
28 января 2005 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by hell_admin
Спасиба, буду переваривать информацию.
А где можно об этом всем почитать, а то во всех книжках по билдеру которые мне попадались, только и описывается, как создавать нотепады да калькуляторы... а сам механизм ни где не описывается.Все на уровне нажмите туда получите то.


Читай "Руководство разработчика". Вышла неплохая книжка, чтото типа "углубленные приемы программирования в билдере" - не помню точно названия - Архангельского и Томилина. Справка. Страуструп. Исходники. Страуструп пожалуй в начале.

259
28 января 2005 года
AlexandrVSmirno
1.4K / / 03.12.2004
Цитата:
Originally posted by kot_

Александр, богатая фантазия - дело хорошее, но первым был барон, который сам себя за волосы из болота вытащил...:) Если владелец явно не указан - то это приложение. И форма будет разрушена только по завершении работы приложения...


К вопросу о фантазии и баронах (VCL sources forms.pas)

Код:
procedure TCustomForm.Close;
var
  CloseAction: TCloseAction;
begin
  if fsModal in FFormState then
    ModalResult := mrCancel
  else
    if CloseQuery then
    begin
      if FormStyle = fsMDIChild then
        if biMinimize in BorderIcons then
          CloseAction := caMinimize else
          CloseAction := caNone
      else
        CloseAction := caHide;
      DoClose(CloseAction);
      if CloseAction <> caNone then
        if Application.MainForm = Self then Application.Terminate
        else if CloseAction = caHide then Hide
        else if CloseAction = caMinimize then WindowState := wsMinimized
        else [color=red]Release;[/color]
    end;
end;
1
28 января 2005 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by AlexandrVSmirno

К вопросу о фантазии и баронах (VCL sources forms.pas)
Код:
procedure TCustomForm.Close;
var
  CloseAction: TCloseAction;
begin
  if fsModal in FFormState then
    ModalResult := mrCancel
  else
    if CloseQuery then
    begin
      if FormStyle = fsMDIChild then
        if biMinimize in BorderIcons then
          CloseAction := caMinimize else
          CloseAction := caNone
      else
        CloseAction := caHide;
      DoClose(CloseAction);
      if CloseAction <> caNone then
        if Application.MainForm = Self then Application.Terminate
        else if CloseAction = caHide then Hide
        else if CloseAction = caMinimize then WindowState := wsMinimized
        else [color=red]Release;[/color]
    end;
end;


Вот ты не угомонный...:)
Ну посмотри внимательней - это происходит только в том случае если...
[color=red]if CloseAction <> caNone[/color] и при этом CloseAction не caHide или caMinimize
т.е. если в событии OnClose у тебя записано -
Action = caFree - или же форма является главной для приложения - только тогда происходит разрушения объекта (ну и естественно если ты в том же событии не вызвал delete - ну тогда от ошибок доступа сам отбивайся...:) ). Во всех остальных случаях деструктор не вызывается и удалить объект из памяти можно только вызвав delete. И надо сказать даже в этом случае память системе не возвращается до завершения программы. Просто программа использует ее под свои нужды. Вот с этим я еще не разобрался.

259
28 января 2005 года
AlexandrVSmirno
1.4K / / 03.12.2004
Цитата:
Originally posted by kot_

Вот ты не угомонный...:)
Ну посмотри внимательней - это происходит только в том случае если...
[color=red]if CloseAction <> caNone[/color] и при этом CloseAction не caHide или caMinimize
т.е. если в событии OnClose у тебя записано -
Action = caFree - или же форма является главной для приложения - только тогда происходит разрушения объекта (ну и естественно если ты в том же событии не вызвал delete - ну тогда от ошибок доступа сам отбивайся...:) ). Во всех остальных случаях деструктор не вызывается и удалить объект из памяти можно только вызвав delete. И надо сказать даже в этом случае память системе не возвращается до завершения программы. Просто программа использует ее под свои нужды. Вот с этим я еще не разобрался.


Вот и выходит говорим об одном и том-же, только по разному. Проблема коммуникации. А то что указатель не чистится - это правда. Но я думаю, что память в кучу всетаки возврашается. У Борланда всегда было свое управление кучей.
ЗЫ Попробовал сделать два раза подряд new, delete. У меня очень интересные результаты получились. Оба раза this у формы один и тот же. Опитимизация мать....

1
28 января 2005 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by AlexandrVSmirno

Вот и выходит говорим об одном и том-же, только по разному. Проблема коммуникации.


Ну если так - разобрались...:)

Цитата:
Originally posted by AlexandrVSmirno

А то что указатель не чистится - это правда. Но я думаю, что память в кучу всетаки возврашается. У Борланда всегда было свое управление кучей.
ЗЫ Попробовал сделать два раза подряд new, delete. У меня очень интересные результаты получились. Оба раза this у формы один и тот же. Опитимизация мать....


Память в кучу возвращается - но только по завершении приложениия. Я с этим столкнулся как то, мне надо было в вектор загнать куевую тучу картинок в вектор, что бы не читать с диска. И я был приятно удивлен, что не смотря на все мои изыски( как я только не пробовал все это удалять...:) и "умные" указатели пытался использовать - ну может не очень умно использовал ) моя програмулина радосно отхавывала куски памяти и даже не кривилась. И желания возвращать ее что то я не заметил...:) Точнее возвращала - к примеру 7М из 50М...Так я с этим до конца и не разобрался - пришлось обходиться без вектора.

487
29 января 2005 года
ddnh_bc
301 / / 16.09.2003
Цитата:
Originally posted by AlexandrVSmirno

К вопросу о фантазии и баронах (VCL sources forms.pas)
Код:
procedure TCustomForm.Close;
var
  CloseAction: TCloseAction;
begin
  if fsModal in FFormState then
    ModalResult := mrCancel
  else
    if CloseQuery then
    begin
      if FormStyle = fsMDIChild then
        if biMinimize in BorderIcons then
          CloseAction := caMinimize else
          CloseAction := caNone
      else
        CloseAction := caHide;
      DoClose(CloseAction);
      if CloseAction <> caNone then
        if Application.MainForm = Self then Application.Terminate
        else if CloseAction = caHide then Hide
        else if CloseAction = caMinimize then WindowState := wsMinimized
        else [color=red]Release;[/color]
    end;
end;



Пример Дельфевого кода.
Pascal и C несколько разные языки.
Соответсвенно и разница в работе с классами - как небо и земля.

Так что в C++ - никаких Release и.т.п.
Создать класс - new - удалить - delete. Никак иначе.

Пока не сделать delete - класс у тебя по-любому будет присутствовать. Никакие Release и Close этому не помогут.

1
29 января 2005 года
kot_
7.3K / / 20.01.2000
Цитата:
Originally posted by ddnh_bc


Так что в C++ - никаких Release и.т.п.
Создать класс - new - удалить - delete. Никак иначе.


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

 
Код:
fmModal = new TfmModal(NULL);
 if(fmModal->ShowModal()==mrOk)ShowMessage("Ok");
 delete fmModal;

 
Код:
fmModal = new TfmModal(NULL);
 if(fmModal->ShowModal()==mrOk)ShowMessage("Ok");
 fmModal->Free();

 
Код:
fmModal = new TfmModal(NULL);
 if(fmModal->ShowModal()==mrOk)ShowMessage("Ok");
 fmModal->Release();

- может тебя это удивит - но очистка памяти происходит во всех трех случаях. И все три случая вполне корректно отрабатывают. Ошибка у парня вылетала не в связи с тем, функцию ли или оператор он использовал для удаления. Скорее всего, он просто нах%евертил гдето в реализации сего - т.е. или пытался удалять удаленный объект, вариантов тут много.
Другое дело, надо ли полагатся на реализацию функций, или лучше использовать нормальный синтаксис языка - тут уже на усмотрение разработчика.
Кроме того, не нужно ставить знак равенства между ANSI C++ и C++Bilder.
259
01 февраля 2005 года
AlexandrVSmirno
1.4K / / 03.12.2004
Цитата:
Originally posted by ddnh_bc


Пример Дельфевого кода.
Pascal и C несколько разные языки.
Соответсвенно и разница в работе с классами - как небо и земля.

Так что в C++ - никаких Release и.т.п.
Создать класс - new - удалить - delete. Никак иначе.

Пока не сделать delete - класс у тебя по-любому будет присутствовать. Никакие Release и Close этому не помогут.


Языки то разные да VCL один и написан он на Паскале.

Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог