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

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

05.04.2013, 09:36. Показов 2488. Ответов 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
8484 / 6151 / 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
8484 / 6151 / 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
8484 / 6151 / 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
8484 / 6151 / 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
8484 / 6151 / 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
8484 / 6151 / 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
Ответ Создать тему
Новые блоги и статьи
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост.
Programma_Boinc 28.12.2025
Советы по крайней бережливости. Внимание, это ОЧЕНЬ длинный пост. Налог на собак: https:/ / **********/ gallery/ V06K53e Финансовый отчет в Excel: https:/ / **********/ gallery/ bKBkQFf Пост отсюда. . .
Кто-нибудь знает, где можно бесплатно получить настольный компьютер или ноутбук? США.
Programma_Boinc 26.12.2025
Нашел на реддите интересную статью под названием Anyone know where to get a free Desktop or Laptop? Ниже её машинный перевод. После долгих разбирательств я наконец-то вернула себе. . .
Thinkpad X220 Tablet — это лучший бюджетный ноутбук для учёбы, точка.
Programma_Boinc 23.12.2025
Рецензия / Мнение/ Перевод Нашел на реддите интересную статью под названием The Thinkpad X220 Tablet is the best budget school laptop period . Ниже её машинный перевод. Thinkpad X220 Tablet —. . .
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Как объединить две одинаковые БД Access с разными данными
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru