Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: 1 2 [Все]   Вниз
  Печать  
Автор Тема: работа delete  (Прочитано 53771 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« : 04-09-2008 04:25 » 

туплю, пните, где не прав (

насколько я понял из издевательств над объектами в отладчике, неважно под какой объект была выделена память при помощи new , даже если указатель привести к (void*) , а потом delete его (речь не про массив, а про один объект) , то память возвращается вся (но, естественно, деструктор не будет вызван - это понятно)
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 04-09-2008 04:27 » 

то есть, если выделена память под DWORD dwd, а удалим как
delete (BYTE*)&dwd
то все 4 байта вернутся в кучу, а не 1 только  ?
Записан

lapulya
Молодой специалист

ru
Offline Offline

« Ответ #2 : 04-09-2008 05:41 » 

Алексей1153++, Вопрос касается только про дебаг моду или и про релиз? Просто что касается дебага, то тут что компилятор хочет то и делает, а вот про Релиз точно ответить не могу - не знаю. Но помоему вроде в релизе должны быть проблемы.
Записан

С уважением Lapulya
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 04-09-2008 05:44 » 

ну то есть лучше всё таки сделать виртуальный метод и в производном классе чётко самого себя удалить этим методом ? (через указатель родителя)
Записан

Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #4 : 04-09-2008 06:08 » 

Алексей1153++, виртуальный деструктор должен быть ВСЕГДА, но если ты его укажешь, только в родителе ничего страшного, будет дефолтовый виртуальный деструктор, который позовёт все деструкторы членов потомка.
Записан

Странно всё это....
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #5 : 04-09-2008 06:08 » 

хм, тоже туплю: а точно такая конструкция сработает? delete (BYTE*)&dwd
если сработает, то мне кааца, что на (BYTE*) будет наплевать.
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #6 : 04-09-2008 06:10 » 

LogRus, яне про деструктор говорю (он и так есть, и так виртуальный). А про виртуальный метод, в котором сделается delete this )
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #7 : 04-09-2008 06:11 » 

McZim, даже (void*) прокатило )
Записан

Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #8 : 04-09-2008 07:28 » 

Алексей1153++, эх Алексей, руки бы тебе оторвать за такие извращения (^_^)

нафига тебе это нужно?
Записан

Странно всё это....
sss
Специалист

ru
Offline Offline

« Ответ #9 : 04-09-2008 08:19 » 

Алексей1153++, в конечном итоге работа delete сводится в любом случае к вызову одной из функций (в случае Windows) HeapFree, LocalFree, GlobalFree, которым абсолютно наплевать  на тип блока памяти.
Записан

while (8==8)
lapulya
Молодой специалист

ru
Offline Offline

« Ответ #10 : 04-09-2008 09:52 » 

sss, речь идет о размере, а не о типе. Понятное дело что delete что-то освободит, вопрос что именно (ну а конкретнее сколько). Ну это при условии что я правильно понял Леху...)))
Записан

С уважением Lapulya
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #11 : 04-09-2008 10:30 » 

lapulya, но при вызове free в обычном C ты указываешь размер?
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #12 : 04-09-2008 10:41 » 

dimka, насколько я понял:

MATRIX* mat;

free((char*)mat->data)
free(mat->data)
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #13 : 04-09-2008 11:33 » 

Ребят, при освобождении передаётся хендл на блок памяти. То что Лёшка написал это просто кастинг при обращении к этому блоку памяти, для удаления это не имеет значения.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #14 : 04-09-2008 11:41 » 

Джон, я так понял, как раз интересует Леху, пи кастинге сколько будет освобождено памяти? Опять так и если я правильно понял.
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #15 : 04-09-2008 11:46 » 

Макс, кастинг это оператор. Те имеет значение возвращаемое значение. А для оператора dlete важно, что параметр - указатель, поэтому это работает и при void* и кастинг здесь не делает никакой погоды.

Согласен с LogRus.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #16 : 04-09-2008 11:49 » 

Джон, ну так все таки, сколько будет в граммах Улыбаюсь
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #17 : 04-09-2008 11:58 » 

Ровно столько сколько было выделено. С точностью до байта. Ага
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #18 : 04-09-2008 12:02 » 

значит, вот тут я был прав.
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #19 : 04-09-2008 13:32 » 

А кто тебе сказал, что ты там не прав? Лёшка же тебе даже сказал, что даже void* прокатит.


зы При условии конечно (как и в твоём вторм примере), что указатели будут правильно проинициаллизированы.
« Последнее редактирование: 04-09-2008 13:34 от Джон » Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #20 : 04-09-2008 13:47 » 

А вызов деструктора в случае приведения к void* разве сработает?
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
McZim
Команда клуба

ru
Offline Offline
Пол: Мужской
Я странный


WWW
« Ответ #21 : 04-09-2008 13:59 » 

Джон, я не про то что даже void* сработает, а про то что: если сработает, то мне кааца, что на (BYTE*) будет наплевать.
Записан

The CBO without stats is like a morning without coffee. (c) T.Kyte.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #22 : 04-09-2008 14:19 » 

деструктора - не сработает. Но это отдельная задача , я просто принцип спрашиваю же, то есть что delete освободит память в любом раскладе. А дальше я уже соображу Улыбаюсь

Алексей1153++, эх Алексей, руки бы тебе оторвать за такие извращения (^_^)
нафига тебе это нужно?
уже ответил строчкой выше Улыбаюсь
Записан

Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #23 : 04-09-2008 21:56 » 

В методе класса можно вызывать delete this; без каких либо последствий. Самое главное, чтобы после данного вызова не было обрашений к не статическим переменным и другим методам данного класса. Т.е. в идеальном случае, после вызова удаления класса, нужно сразу выходить из метода.

Если где то делать кастинг указателя класса скажем на void *, и затем удалять, то проблемы возникнут с течью памяти, если в данном классе переменные были созданы динамически.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #24 : 05-09-2008 03:05 » 

Нет, ну вот зачем? Зачем? Что, млин за грязные хаки?
Записан

Странно всё это....
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #25 : 05-09-2008 05:31 » 

Finch, так и сделал, вызывается "родной" delete через виртуальную процедуру, а далее считается, что объекта нет

ЛогРус, расслабься Улыбаюсь) Просто вникаю в суть, это нигде в таком виде не будет использовано. В любом случае, я не боюсь указателей Улыбаюсь
Записан

Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #26 : 05-09-2008 05:40 » 

Алексей1153++, да я не напрягаюсь Улыбаюсь и указателей кстати тоже не боюсь Улыбаюсь я их просто не люблю
Записан

Странно всё это....
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #27 : 05-09-2008 06:51 » 

Finch,

ой, "а вот с этого места, пожалуйста, поподробней" (С), т.е. теперь для меня тупой еще раз и помедленней:
зачем тебе в самом классе в одном из его методов вызывать delete this? Какой смысл? "Где деньги, Зин?" (С) Ага  Для чего это может использоваться?   
Если объект класса был создан кем-то, то он тем самым кем-то должен быть и убран, дабы не путаться. Ну а в обычной жизни для объекта класса при его умирании и так будет вызван деструктор, который все почистит.
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #28 : 05-09-2008 07:02 » 

Ирин, речь про вот что:
Код:
struct A
{
   virtual void deleteThis()=0;
};

struct B:A
{
   ...
   void deleteThis()
   {
     delete this;
   }
};

struct C:A
{
   ...
   void deleteThis()
   {
     delete this;
   }
};

//-------------

A* pVirt=0;

if(условие)
{
   pVirt=new B;
}
else
{
   pVirt=new C;
}

...

//как удалять будем ?

//так
delete pVirt;
pVirt=0;

//или так
pVirt->deleteThis();
pVirt=0;

придерживаюсь второго варианта всё же Улыбаюсь . Там и деструкторы правильно вызовутся
« Последнее редактирование: 05-09-2008 07:04 от Алексей1153++ » Записан

sss
Специалист

ru
Offline Offline

« Ответ #29 : 05-09-2008 07:06 » 

Malaja, например в методе Release() объекта с подсчетом ссылок.

Код:
u_long __stdcall CLifeControlObject::Release(void)
{
  long lRC = ::InterlockedDecrement((long *) &m_ulRefCount);
  if ( lRC == 0)
  {
    delete this;
    return 0;
  }
#ifdef _DEBUG
  if ( lRC < 0)
  {
    SHOWTHROW( TEXT("Вызов Release() без AddRef()"), ClassName);
  } 
#endif 
  return lRC;
}
Записан

while (8==8)
Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #30 : 05-09-2008 07:10 » 

Леш, а в первом случае они тоже правильно вызовутся, т.к. деструктор в любом объекте присутствует всегда. А если у тебя в классе есть динамически созданные объекты, так тебя и второй вариант не спасет...
Или я в чем-то неправа?

sss,
спасибо за пример! Об этом варианте я не подумала.
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
sss
Специалист

ru
Offline Offline

« Ответ #31 : 05-09-2008 07:24 » 

Не за что Malaja  Скромно так.... Еще надо добавить, что естественно метод Release() и деструктор виртуальные...
Записан

while (8==8)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #32 : 05-09-2008 07:55 » 

Цитата
Леш, а в первом случае они тоже правильно вызовутся, т.к. деструктор в любом объекте присутствует всегда. А если у тебя в классе есть динамически созданные объекты, так тебя и второй вариант не спасет...
Или я в чем-то неправа?
для первого случая надо обязательно делать виртуальные деструкторы, а во втором про это можно не думать Улыбаюсь
Записан

Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #33 : 05-09-2008 08:25 » 

Леш, почему??? В классе деструктор всегда присутствует незримо, даже если ты его не прописываешь!
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #34 : 05-09-2008 08:30 » 

потому что если не объявить в родителе деструктор как виртуальный, то
delete pVirt
вызовет только ~A . Если объявить, то вызовется ~потомок, ~A.

А второй случай всегда правильно вызовет деструкторы
Записан

Malaja
Команда клуба

de
Offline Offline
Пол: Женский

« Ответ #35 : 05-09-2008 08:47 » 

А ты их совсем замять хотел? Тогда пардон, я думала, что как минимум в классе А ты его объявишь в любом случае... Тогда все ясно. Извини за старческий маразм Ага
Я же не думала, что ты так обидишь деструктор Ага
Записан

холоднокровней, Маня, Ви не на работе
---------------------------------------
четкое определение сущности бытия:
- А мы в прошлом или в будущем?- спросила Алиса.
- Мы в жопе, - ответил кролик.
- А "жопа" - это настоящее? - спросила Алиса.
- А "жопа" - это у нас символ вечности.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #36 : 05-09-2008 08:55 » 

да, я такой Отлично
Записан

Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #37 : 05-09-2008 08:59 » 

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

Лёха, ты же один хрен объявил виртуальную функцию и  у тебя объект вырос на ptr_size + создалась табилица. Улыбаюсь ну объяви виртуальный деструктор хотя бы пустой в одном родительском классе. так в чём разница кроме мерзких извращений, не считая случая с подсчётом ссылок.
Записан

Странно всё это....
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #38 : 05-09-2008 09:01 » 

у нас разные взгляды на мир Улыбаюсь Для меня твои подсчёты ссылок - и есть грязное и )))
Записан

Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #39 : 05-09-2008 11:04 » 

Ирин, Как пример: паттерн программирования Singleton. Там правда в статическом методе удаляется класс из памяти. Хотя можно и обычный метод использовать.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Dimka
Деятель
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #40 : 05-09-2008 11:35 » 

Не пойму я чего-то.

Когда мы объявляем класс B потомком A, а затем приводим объект типа B к типу A, мы используем полиморфизм объекта.

Чтобы полиморфизм объекта работал (в данном случае вызывался нужный деструктор), по синтаксическим особенностям C++  переопределяемые потомками методы необходимо объявить виртуальными, что разрешает полиморфизм объекта.

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

Где логика, где здравый смысл? Улыбаюсь
Записан

Программировать - значит понимать (К. Нюгард)
Невывернутое лучше, чем вправленное (М. Аврелий)
Многие готовы скорее умереть, чем подумать (Б. Рассел)
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #41 : 05-09-2008 11:38 » 

да одни сплошные эксперименты )
Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #42 : 27-01-2009 08:27 » 

В продолжение темы.

Понимаю, что боян, но очень туго со временем...
Могу ли я удалить динамический объект из его собственного конструктора? Особенно в случае наследования (это MDI форма и у нее автоматом происходит Show()).

Код: (C++)
class A
{
  A(int a) : B(int b)
  {
    delete this;
  };
};

A *a = new A(0);
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #43 : 27-01-2009 08:45 » 

Я думаю, можно. Просто в A *a будет указатель на освобождённую память.
Ну а на стеке будет падать, конечно Улыбаюсь Поэтому всё равно лучше такой опасный конструктор спрятать за фабричный метод, и удалять именно в фабричном методе, если что-то не понравилось Улыбаюсь
« Последнее редактирование: 27-01-2009 08:50 от Вад » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #44 : 27-01-2009 08:54 » 

можно, только для чего ? )
Записан

Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #45 : 27-01-2009 10:05 » 

Ром, в таких случаях лучше всего на нагружать конструктор функциональностью, а использовать ф-ю Init.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #46 : 27-01-2009 12:30 » 

Да я уже извернулся - просто сам факт интересен. Ведь после конструктора срабатывают всякие события, а значит в очереди стоят сообщения (вероятно класс-предок послал послал PostMessage).

Для чего все это...
Был диалог, который создавался через new, в его public-члены загружались параметры и вызывался ShowModal. Нужно было быстро переделать его в MDI, но MDI не может быть модальным и, соотв., delete ему в вызывающем коде не сделаешь, а нужно было сделать контроль, чтобы таких диалогов (с данными уникальными параметрами) одновременно был только один. Хотел проверять в конструкторе и удалять сам себя в случае повтора. Решил задачу проверкой вне класса - до создания.
« Последнее редактирование: 27-01-2009 12:36 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Джон
просто
Администратор

de
Offline Offline
Пол: Мужской

« Ответ #47 : 27-01-2009 12:35 » 

Сам факт - это да. new и delete это по сути операторы С++, в итоге они вызовут ф-ции выдлеления/освобождения памяти, и вот как оно там будет... Надо просто на уровне асма продебажить. Я думаю всё станет ясно.
Записан

Я вам что? Дурак? По выходным и праздникам на работе работать. По выходным и праздникам я работаю дома.
"Just because the language allows you to do something does not mean that it’s the correct thing to do." Trey Nash
"Physics is like sex: sure, it may give some practical results, but that's not why we do it." Richard P. Feynman
"All science is either physics or stamp collecting." Ernest Rutherford
"Wer will, findet Wege, wer nicht will, findet Gründe."
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #48 : 27-01-2009 12:37 » 

Не, в дебри асма лезть желания нет. Потом, смениться версия runtime-библиотек и ситуация может измениться.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #49 : 27-01-2009 18:06 » 

а по моему лучше просто переопределить виртуальную DefWindowProc и поставить заглушку

return 0;

тогда сообщения не обработаются.
Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #50 : 27-01-2009 18:52 » 

Леш, в моем случае это Borland C++ Builder 6 - тут большая классовая надстройка и до корней не докопаешься. Задачу я уже решил - традиционным методом:
1. При создании где-то сохраняем указатель на форму.
2. При закрытии (и самоуничтожении) формы в OnClose это где-то обнуляем.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #51 : 27-01-2009 20:14 » 

В свое время, мне посоветовали использовать исключения в данном случае. При ошибке в конструкторе класса вызывать исключение, а уже в основной ветке программы ловить исключения. Также сказали, что класс в данном случае автоматически уничтожается. Хотя я тогда не проверял. Да и в принципе и не использовал данный метод.
« Последнее редактирование: 27-01-2009 20:17 от Finch » Записан

Не будите спашяго дракона.
             Джаффар (Коша)
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #52 : 27-01-2009 20:32 » 

При случае попробую.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #53 : 27-01-2009 21:09 » 

Сейчас провел эксперементы.
Код:
#include <stdio.h>

class DivideByZeroError
{
public:
   DivideByZeroError():message("Ошибка: Деление на нуль\n") {}//Error: Divide By Zero\n") {}
   void printMessage() const {printf("%s", message);}
private:
   const char *message;
};

class prob
{
public:
   prob() {printf("Constructor\n"); i=new int[20]; throw DivideByZeroError();};
   ~prob() {printf("Destructor\n"); delete [] i;};
private:
   int *i;
   
};

int main()
{
   prob *my=0;
   try
   {
      my = new prob();
   }
   catch(DivideByZeroError error)
   {
      error.printMessage();
      if (my) delete my;
   }
   
   return 0;
}
Объект не создается. Но также и не вызывается деструктор автоматически. Все динамически созданные данные теряются. Поэтому перед throw нужно их удалять.
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Вад
Модератор

ru
Offline Offline
Пол: Мужской

« Ответ #54 : 27-01-2009 22:23 » 

Finch, поэтому я неоднократно встречал резонную рекомендацию не хранить динамические поля напрямую при небезопасных конструкторах. Скажем, у Мейерса в "More Effective C++". Предлагается помещать их в умные указатели - они, как полностью сконструированные на момент исключения объекты, должны быть удалены корректно при возникновении исключения в конструкторе (их освобождение - как статических элементов - не требует вызова деструктора содержащего их класса, а у них самих деструкторы вызваны будут)
Записан
sss
Специалист

ru
Offline Offline

« Ответ #55 : 28-01-2009 03:42 » 

Finch, вот возможное решение...

Код:
class A
{
protected:
  void* b;
  A() : b(NULL) {};
  ~A(){ if ( b) free( b);};
}

class B : public A
{
public:
   B() { b = malloc( 100); throw EError;};
}
Записан

while (8==8)
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #56 : 28-01-2009 06:14 » 

Объект не создается. Но также и не вызывается деструктор автоматически. Все динамически созданные данные теряются. Поэтому перед throw нужно их удалять.

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

Вад, согласен, так всегда и делаю Улыбаюсь
Записан

Странно всё это....
sss
Специалист

ru
Offline Offline

« Ответ #57 : 28-01-2009 07:32 » 


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


Гм... Интересное замечание. Кажется есть опции в компиляторе меняющие это поведение ( во всяком случае я ловил такие моменты). Если в проекте есть статические и динамические экземпляры лучше на это не полагаться. Кстати, мой пример выше - "умный" базовый класс, который точно уже положил вызов деструктора при раскручивании...
Записан

while (8==8)
Finch
Спокойный
Администратор

il
Offline Offline
Пол: Мужской
Пролетал мимо


« Ответ #58 : 28-01-2009 13:15 » 

LogRus
Цитата
~$ g++ --version
g++ (GCC) 4.3.2 20081105 (Red Hat 4.3.2-7)
Проверял, что нет течи памяти с помошью valgrind-3.3.0
Записан

Не будите спашяго дракона.
             Джаффар (Коша)
Антон (LogRus)
Глобальный модератор

ru
Offline Offline
Пол: Мужской
Внимание! Люблю сахар в кубиках!


WWW
« Ответ #59 : 29-01-2009 06:09 » 

Finch, да был не прав (хотя много месяцев именно так и думал), в стандарте ничего про это не нашел, компиляторы которые были под рукой реагируют, также как у тебя.
Записан

Странно всё это....
Страниц: 1 2 [Все]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines