Форум программистов, компьютерный форум, киберфорум
C++ Builder
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.55/11: Рейтинг темы: голосов - 11, средняя оценка - 4.55
6 / 6 / 3
Регистрация: 06.02.2013
Сообщений: 71

Ошибки, связанные с деструктором

05.04.2013, 09:36. Показов 2509. Ответов 20
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Здравствуйте Всем! Вот такой вопрос. Может плохо сформулированный, но не знаю как
и взяться за него! В C++Builder v.6 сделан класс (например TForm_Unit). Этот класс в
своем конструкторе создает примерно полтора десятка динамических VCL-компонентов
(ГроупБокс, Клавиши, Метки, Едит, СтрингГрид). В этом-же классе определен деструктор,
который все эти динамические VCL-компоненты, как и учат отцы-основатели, по очереди
удаляет. Типа:
C++
1
2
if ( Butt_Acc != NULL )    delete    Butt_acc;
// .........
Этот класс много работает со всеми этими VCL-компонентами с пом. своих методов. Но
когда выполняются определенные действия (например сохранение всей информации в
файл) выскакивают непонятные ран-тайм сообщения об ошибках. Типа того, что где-то
прочитаны неверные адреса! Доступ к чему-то запрещен! С самим сохранением в файл
все нормально, т.к. оно производится правильно и проверялось до этого отдельно.
Самое интересное! Если заменить мой расколбасанный деструктор на простое:
C++
1
~TForm_Unit()    {};
т.е. доверить самой среде C++Builder убирать отслужившие динамические VCL-компоненты,
то Все Работает Нормально! Как часы! Что бы это означало? Заранее Всем благодарен
за умные и полезные мысли! ...
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
05.04.2013, 09:36
Ответы с готовыми решениями:

Ошибки связанные с wininet
Здравствуйте. Проект выглядит так: #include "stdafx.h" #include <windows.h> #include <stdio.h> #include <fstream> ...

Ошибки связанные с api vk
Код: def testpost(): session = vk.AuthSession(app_id='5418092', user_login='mylogin@vk.com', user_password='pass') api =...

Ошибки связанные с 'navigator object'.
Привет всем. Я используя браузер "Netscape 7.2". В 'JavaScript' коде время от времени возникают ошибки связанные с 'navigator object'....

20
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
05.04.2013, 10:29
Okonenko Stanis, во-первых, покажите как создаете объекты на форме. Во-вторых, при вызове delete pointer; не нужно проверять pointer на NULL.
0
Диссидент
Эксперт C
 Аватар для Байт
27714 / 17332 / 3810
Регистрация: 24.12.2010
Сообщений: 38,978
05.04.2013, 10:34
Okonenko Stanis, Если ваш класс является владельцем (Owner) ваших компонентов, то он их и удалит
0
6 / 6 / 3
Регистрация: 06.02.2013
Сообщений: 71
05.04.2013, 17:35  [ТС]
- Конструктор моего класса такой:
C++
1
2
3
4
TForm_Unit(
    TComponent*    Owner,
    const int      _top,
    const int      _left );
Ему передается: владелец всего этого хозяйства Owner - указатель на Форму,
_top, _left - координаты расположения всего хозяйства на Форме.
А внутри конструктора по очереди создаются все динам. VCL-компоненты.

Сначала создается ГроупБокс:
C++
1
2
3
4
5
6
7
8
9
10
    GB = new    TGroupBox( Owner );
    GB->Parent = (TWinControl*)Owner;
    // заглавие.
    GB->Caption = ".....";
    // размеры.
    GB->Width = 360;
    GB->Height = 200;
    // положение.
    GB->Top = _top;
    GB->Left = _lrft;
Далее подобным образом создаются все остальные динам. VCL-компоненты,
только в качестве предка (Parent) им задается уже выше созданный ГроупБокс.

- Да, появились новые сведения - при сохранении в файл сразу после
сохранения почему-то вызывается злополучный деструктор!!! Сохранение
делается с помощью перегруженного оператора вставки!
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
05.04.2013, 17:59
Приведи код компонента полностью
0
6 / 6 / 3
Регистрация: 06.02.2013
Сообщений: 71
06.04.2013, 00:08  [ТС]
- Всего там очень много. Я уже говорил, создается полтора десятка динам.
VCL-компонентов. Но набросок я могу привести ...
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
class   TForm_Unit
{
private:
    // указатель на ГроупБокс - "Формульная Единица".
    TGroupBox*    GB;
    // *** Указатели на остальные динам. VCL-компоненты. ***
    // указатель на Клавишу - "Сохранить".
    TButton*    B_Save;
    // обработчик нажатия мышью на Клавишу "Сохранить".
    void __fastcall    B_SaveClick( TObject*    Sender );
    // и т.д. .........
 
    // *** Данные с которыми работает класс. ***
    // .........
 
public:
 
    // *** перегрузка операторов. ***
    // перегрузка оператора вставки.
    friend ostream&    operator<<( ostream&    stream, const TForm_Unit    fu );
    // перегрузка оператора извлечения.
    friend istream&    operator>>( istream&    stream, TForm_Unit&    fu );
 
};
Насколько я понимаю вся крамола в том, что сразу после работы перегруженного
оператора вставки вызывается деструктор!
Может быть дело в том, что вызывается оператор вставки из метода самого класса
TForm_Unit. Точнее так: - одним из динам. VCL-компонентов данного класса,
создаваемых в конструкторе данного класса является - Кнопка (B_Save). Обработчик
ее нажатия мышью (B_SaveClick) является членом класса TForm_Unit. А вызов
перегруженного, дружественного оператора вставки осуществляется примерно так:

C++
1
2
3
4
5
6
7
8
9
10
11
// обработчик нажатия мышью на Клавишу "Сохранить".
void __fastcall    TForm_Unit::B_SaveClick( TObject*    Sender )
{
    // открыть выходной файловый поток.
    open_out_file( "out_file_name", 4 );    //(const int)
    // вывод структуры в выходной файловый поток.
    fout << *this;    //(!!!!!)
    fout << endl;
    // закрыть выходной файловый поток.
    fout.close();
}
Почему вызывается деструктор? ...
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
06.04.2013, 00:16
Так зачем вам Sender ?
Где конструктор/деструктор класса ?
Почему класс называется TForm_Unit хотя вообще никакого отношения к VCL- форме не имеет ?

Добавлено через 5 минут
Код- жуть
0
6 / 6 / 3
Регистрация: 06.02.2013
Сообщений: 71
07.04.2013, 10:52  [ТС]
- А я никогда не говорил, что это VCL-компонент. Это обычный класс, который
создает много динамических VCL-компонентов. Я набросал маленькое тестовое
приложение. Оно вызывает перегруженный оператор вставки из 1) метода самого
класса и 2) из метода основной формы. Несанкционированный вызов деструктора
класса TCls происходит в обеих случаях. У кого-ни-будь есть мысли ПОЧЕМУ? ...
- Подробные пояснения к приложению даны в файле реализации основной формы
(Main_Form_Unit.cpp). Меткой //(BP) помечена строка, где надо поставить точку
останова, чтобы видель несанкционированное срабатывание деструктора.
Вложения
Тип файла: rar Test_operator.rar (491.2 Кб, 2 просмотров)
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
07.04.2013, 13:10
Цитата Сообщение от Okonenko Stanis Посмотреть сообщение
то обычный класс, который
создает много динамических VCL-компонентов.
Почему его тогда не сделать VCL ?
1
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
07.04.2013, 13:26
Цитата Сообщение от Okonenko Stanis Посмотреть сообщение
C++
1
friend ostream& operator<<( ostream& stream, const TForm_Unit fu );
Здесь собака порылась.

При вызове данного оператора создается копия инстанции класса с помощью конструктора копирования, предоставляемого компилятором за неимением такового в объявлении класса. Соответственно, в этой копии оказываются все указатели из оригинальной инстанции. Время жизни копии равно времени выполнения функции оператора - по окончании все объекты в стэке разрушаются, в том числе и наша копия. Вызывается деструктор, память по указателям освобождается - все. Теперь указатели в оригинальной инстанции класса неверны, обращение по ним вызывает access violation.

Чтобы выйти из положения, тщательно следи за возможностью явного или неявного копирования, либо напиши свой конструктор копирования, который для копии будет выделять собственную память под компоненты из оригинала.
1
6 / 6 / 3
Регистрация: 06.02.2013
Сообщений: 71
07.04.2013, 16:08  [ТС]
- Огромное спасибо Вам BRcr и Avazart! Есть над чем подумать и поэкспериментировать на
моем пробном приложении. Еще раз спасибо! Если что снова не пойдет - сообщу. ...
0
6 / 6 / 3
Регистрация: 06.02.2013
Сообщений: 71
08.04.2013, 15:43  [ТС]
- Не удается мне добиться ничего вразумительного. Действительно при вызове
перегруженного оператора вставки вызывается конструктор копирования. Но видимо
я что-то с ним не так делаю! Все равно вылезают ошибки типа Access Violation.
Прошу Вас BRcr, если Вам не затруднительно, помогите в моем тестовом приложении
"Test_operator.rar" разрулить ситуацию с помощью конструктора копирования!
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
08.04.2013, 16:13
По ссылке передавай в оператор и не должно быть ошибок...

Но сам подход мне не понятен почему сразу не наследоваться от формы или другого компонента ?
0
6 / 6 / 3
Регистрация: 06.02.2013
Сообщений: 71
09.04.2013, 10:32  [ТС]
- Отвечаю на Ваши замечания Avazart. Класс назывался TForm_Unit потому, что
исходная программа, где вылезли все эти сложности имела дело с химией и ее
"формульными единицами". Но это вообще все равно как назвать. Можно конечно
передать экземпляр в оператор вставки по ссылке, но ведь во всех учебниках
почему-то передают именно по значению! Можно конечно сделать этот класс
VCL-компонентом, но во-первых это будет какой-то непонятный химический
компонент, который и назвать-то не знаешь как! А во-вторых что это все даст
с точки зрения проблемы? Хотелось бы раз и навсегда разобраться, чтобы в
дальнейшем свободно пользоваться принципом: - создал САМ динамический
VCL-компонент, САМ его и удаляешь!
0
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
09.04.2013, 14:23
Цитата Сообщение от Okonenko Stanis Посмотреть сообщение
Можно конечно
передать экземпляр в оператор вставки по ссылке, но ведь во всех учебниках
почему-то передают именно по значению!
Нонсенс. Выкидывай все такие учебники и не читай впредь всякую ересь. В программировании все определяется эффективностью, а создавать временные копии в стэке чего-либо размером более стандартных типов данных - неэффективно. Иногда это дополнительно также вызывает проблемы, вроде твоей с освобождением памяти.
Так что передавай по ссылкам, указателям. Лучше всего иногда по константным ссылкам для самоконтроля.
Еще очень удобно бывает передавать и возвращать std::auto_ptr<>, но тут надо понимать суть работы этого контейнера.
Цитата Сообщение от Okonenko Stanis Посмотреть сообщение
Хотелось бы раз и навсегда разобраться, чтобы в
дальнейшем свободно пользоваться принципом: - создал САМ динамический
VCL-компонент, САМ его и удаляешь!
Если создаваемый тобою класс принимает в конструкторе параметр AOwner, явной необходимости освобождать память самостоятельно нет, хотя это и можно делать конечно же. Когда класс-владелец твоих компонентов будет разрушаться, также будет освобождена и выделенная под них память.
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
09.04.2013, 15:43
Цитата Сообщение от Okonenko Stanis Посмотреть сообщение
Можно конечно
передать экземпляр в оператор вставки по ссылке, но ведь во всех учебниках
почему-то передают именно по значению!
"Это неправильные пчелы, а значит они делают неправильный мед"
Всегда передается по ссылке что бы не копировать лишний раз объект.

Цитата Сообщение от Okonenko Stanis Посмотреть сообщение
Можно конечно
передать экземпляр в оператор вставки по ссылке, но ведь во всех учебниках
почему-то передают именно по значению! Можно конечно сделать этот класс
VCL-компонентом, но во-первых это будет какой-то непонятный химический
компонент, который и назвать-то не знаешь как!
Непонятно химически это у вас.Он владеет "чужими" объектами которыми ему не принадлежат( принадлежат форме)

Так почему сразу использовать форму - ведь это сам по себе класс!

О создании своих компонентов VCL есть Архангельском.

Добавлено через 3 минуты
В общем непонятно желания лезть в ООП не зная его принципы.
0
6 / 6 / 3
Регистрация: 06.02.2013
Сообщений: 71
09.04.2013, 18:15  [ТС]
- Да, передача объекта-класса в перегруженный оператор вставки по
ссылке конечно решает проблему! Конструкторы копирования не вызываются.
Следовательно, деструкторы не вызываются. Деструктор вызывается один раз
когда удаляется сам объект. В общем - все нормально!
Просто хотелось знать больше и уметь решать и такие сложные ситуации.
Еще раз спасибо Вам Avazart и BRcr за полезные мысли!
Кстати, где лучше всего почитать о таких нетривиальных случаях?
0
Эксперт С++
 Аватар для Avazart
8488 / 6155 / 615
Регистрация: 10.12.2010
Сообщений: 28,683
Записей в блоге: 30
09.04.2013, 18:18
Цитата Сообщение от Okonenko Stanis Посмотреть сообщение
Кстати, где лучше всего почитать о таких нетривиальных случаях?
А где тут не тривиальность ?

Перегрузка операторов есть в любой нормальной книжке по С++.
Про создание компонентов есть в Архангельском.
1
 Аватар для BRcr
4043 / 2333 / 292
Регистрация: 03.02.2011
Сообщений: 5,066
Записей в блоге: 10
09.04.2013, 18:20
Почитай "Exceptional C++" и "More Exceptional C++", автор - Herb Sutter. Занимательное чтиво, поможет писать если не на пределах эффективности, то хотя бы без нелепых ошибок.
1
6 / 6 / 3
Регистрация: 06.02.2013
Сообщений: 71
10.04.2013, 16:17  [ТС]
- Я имею в виду "не тривиальность" в том смысле, что в данном примере можно с легкостью
уйти от этих "деструкторов", но ведь бывают и другие ситуации ... И надо уметь их решать ...
Еще раз спасибо Всем за помощь и подсказки! В том числе и за литературу. Думаю, что тема
уже исчерпана!
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
10.04.2013, 16:17
Помогаю со студенческими работами здесь

PCAP и связанные с ним ошибки
Доброго времени суток. Использую PCAP, чтобы снифать пакеты в своей программе. Она работает, однако есть одна неприятная особенность. ...

Ошибки связанные с ntdll.dll
После отката обновления драйвера видеокарты стали появлятся следующие ошибки: Имя сбойного приложения: MassEffect.exe, версия:...

Ошибки в коде, связанные с boost
ошибки начинаются сразу после использования matrix почему, ее нет? вот ссылка на сайт исходника...

Ошибки связанные с односвязным списком
Здравствуйте... Решила сама разобраться и написать программу, связанную с работой с односвязным списком. Для красоты решила оформить каждое...

Ошибки validator.w3.org связанные с Joomla
Здравствуйте, из неисправленных ошибок при валидации остались ошибки, связанные со вставками joomla. Разметка XHTML 1.0 Transitional, не...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Символьное дифференцирование
igorrr37 13.02.2026
/ * Логарифм записывается как: (x-2)log(x^2+2) - означает логарифм (x^2+2) по основанию (x-2). Унарный минус обозначается как ! в-строка - входное арифметическое выражение в инфиксной(обычной). . .
Камера Toupcam IUA500KMA
Eddy_Em 12.02.2026
Т. к. у всяких "хикроботов" слишком уж мелкий пиксель, для подсмотра в ESPriF они вообще плохо годятся: уже 14 величину можно рассмотреть еле-еле лишь на экспозициях под 3 секунды (а то и больше),. . .
И ясному Солнцу
zbw 12.02.2026
И ясному Солнцу, и светлой Луне. В мире покоя нет и люди не могут жить в тишине. А жить им немного лет.
«Знание-Сила»
zbw 12.02.2026
«Знание-Сила» «Время-Деньги» «Деньги -Пуля»
SDL3 для Web (WebAssembly): Подключение Box2D v3, физика и отрисовка коллайдеров
8Observer8 12.02.2026
Содержание блога Box2D - это библиотека для 2D физики для анимаций и игр. С её помощью можно определять были ли коллизии между конкретными объектами и вызывать обработчики событий столкновения. . . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL_LoadPNG (без SDL3_image)
8Observer8 11.02.2026
Содержание блога Библиотека SDL3 содержит встроенные инструменты для базовой работы с изображениями - без использования библиотеки SDL3_image. Пошагово создадим проект для загрузки изображения. . .
SDL3 для Web (WebAssembly): Загрузка PNG с прозрачным фоном с помощью SDL3_image
8Observer8 10.02.2026
Содержание блога Библиотека SDL3_image содержит инструменты для расширенной работы с изображениями. Пошагово создадим проект для загрузки изображения формата PNG с альфа-каналом (с прозрачным. . .
Установка Qt-версии Lazarus IDE в Debian Trixie Xfce
volvo 10.02.2026
В общем, достали меня глюки IDE Лазаруса, собранной с использованием набора виджетов Gtk2 (конкретно: если набирать текст в редакторе и вызвать подсказку через Ctrl+Space, то после закрытия окошка. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru