Russian Qt Forum
Ноябрь 22, 2024, 22:02 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3   Вниз
  Печать  
Автор Тема: Как вызываются деструкторы  (Прочитано 18028 раз)
AK
Новичок

Offline Offline

Сообщений: 14


Просмотр профиля
« : Декабрь 15, 2020, 11:22 »

Уважаемые специалисты, я, увы, новичок в C++ и Qt вопрос, как следует вызывать деструкторы
1. Правильно ли я понимаю, что динамически-созданные объекты классов, наследующих QObject, всегда уничтожаются Qt автоматически? Т.е. явно вызывать "delete S;" после  "QString S; S = new QString("Abc");..." не нужно?
2. Если я создаю статически, скажем "QString S = "Abc";"  как поле класса, то должен в деструкторе класса обязательно написать "S.~QString();" ?
3. Если я объявил "QString S = "Abc";", как локальную переменную метода, то деструктор можно не вызывать, так как объект S будет размещен в стеке и память выделенная S будет освобождена после завершения выполнения метода?
4. Во всех примерах создания оконных приложений:
int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    MainWindow winMain;
    winMain.show();
    return app.exec();
}

Объект MainWindow создается статически, получается, его деструктор не будет вызван никогда?
Тогда если полями MainWindow у меня являются динамические массивы, то единственная возможность их удались перед завершением работы приложения - написать слот для сигнала  aboutToQuit() QApplication?


« Последнее редактирование: Декабрь 15, 2020, 11:33 от AK » Записан
ssoft
Программист
*****
Offline Offline

Сообщений: 584


Просмотр профиля
« Ответ #1 : Декабрь 15, 2020, 12:19 »

Здесь собственно отвечать не на что. По каждому вопросу нужно отправлять учить основы C++.

1. Нет, не правильно. См. https://doc.qt.io/qt-5/objecttrees.html
2. Нет, не правильно. Что значит статически и что такое деструктор, когда он вызывается и нужно ли его вызывать явно?
3. То же самое. Читайте про область видимости переменных и порядок их инициализации и удаления.
4. Тоже полная ерунда написана. Следует из непонимания 2 и 3.
« Последнее редактирование: Декабрь 15, 2020, 12:23 от ssoft » Записан
AK
Новичок

Offline Offline

Сообщений: 14


Просмотр профиля
« Ответ #2 : Декабрь 15, 2020, 12:48 »

 Я вот и пытаюсь учить, книжки читаю, но вопросы остаются.
1. Спасибо по п. 1 вроде понял: при удалении родителя все дочерние объекты будут также удалены.
2. Частично понятно из п.1. Про "статически" снялся вопрос. Но в основном непонятно. Я представляю себе так: я создал объект QString s="Abc" Где-то в памяти, наверное, в куче, размещено "Abc". Перед закрытием программы следует очистить память. Для этого нужно явно или неявно вызвать деструктор. QString не является наследником другого объекта QObject (п.1), поэтому следует вызвать деструктор явно. Правильно ли я рассуждаю?
3. Из того, что читал следует, что переменные могут размещаться в отдельном сегменте данных (глобальные переменные),  время жизни = времени жизни программы, в стеке (локальные переменные функций и методов) время жизни = времени выполнения функции/метода, в куче там время жизни - пока явно не удалю. Если объект объявлен в методе, он - локальная переменная, все, что его касается, хранится в стеке, правда, он может выделить память в куче. Опять же нужно явно вызывать деструктор получается?
4.  Ну да, я не понимаю ни основы C++ ни специфику Qt, пытаюсь разобраться,  в книжках ответы не нашел, потому и спрашиваю Улыбающийся По моей логике (порочной судя по брезгливому комментарию) надо явно вызвать деструктор MainWindow, в котором освободить всю выделенную под массивы в куче память и вызвать деструкторы всех созданных объектов. Но такой деструктор в изученных мной примерах никто не делает. Очевидно, я где-то не прав, но не понимаю где.
« Последнее редактирование: Декабрь 15, 2020, 12:50 от AK » Записан
Пантер
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 5876


Жаждущий знаний


Просмотр профиля WWW
« Ответ #3 : Декабрь 15, 2020, 12:56 »

У тебя MainWindow создается не статически, а на стеке, он будет автоматически разрушен (с вызовом деструктора) при выходе из функции main. При разрушении экземпляра класса все его не динамические члены так же разрушаются.
« Последнее редактирование: Декабрь 15, 2020, 13:29 от Пантер » Записан

1. Qt - Qt Development Frameworks; QT - QuickTime
2. Не используйте в исходниках символы кириллицы!!!
3. Пользуйтесь тегом code при оформлении сообщений.
AK
Новичок

Offline Offline

Сообщений: 14


Просмотр профиля
« Ответ #4 : Декабрь 15, 2020, 13:26 »

Ааа, Пантер, спасибо большое!
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #5 : Декабрь 15, 2020, 14:07 »

Возможно лучше пожевать что-то одно, напр
3. Если я объявил "QString S = "Abc";", как локальную переменную метода, то деструктор можно не вызывать, так как объект S будет размещен в стеке и память выделенная S будет освобождена после завершения выполнения метода?
Сам по себе S - указатель (грубо говоря), да, размещен в стеке. А вот "Abc" (что может быть очень большим) объект S разместит в куче. При выходе из области видимости S c ним самим ничего не происходит, просто занимаемая этим указателем память будет доступна для использования, и, вероятно, скоро кeм-то будет занята. Но до того автоматычно вызовется деструктор, он освободит "Abc" в куче.

Отсюда следует что "деструктор можно не вызывать" - неверно, здесь правильно "деструктор нельзя вызывать" т.к. это поведет к повторному удалению "Abc" и крашу (в лучшем случае)

Есть простое утверждение типа "деструктор никогда не должен вызываться напрямую", и оно, в общем, верно. Редкие исключения подтверждают это правило. Если хотите изучить "но совесть" - приведите такой редкий пример  Улыбающийся
Записан
AK
Новичок

Offline Offline

Сообщений: 14


Просмотр профиля
« Ответ #6 : Декабрь 15, 2020, 14:31 »

Igors, спасибо!! Очень полезное обсуждение. Прямо чувствую, как умнею! Улыбающийся

Записан
AK
Новичок

Offline Offline

Сообщений: 14


Просмотр профиля
« Ответ #7 : Декабрь 15, 2020, 14:32 »

Буду думать над редким примером
Записан
AK
Новичок

Offline Offline

Сообщений: 14


Просмотр профиля
« Ответ #8 : Декабрь 15, 2020, 14:40 »

В каком-то смысле, явного деструктора требуют динамически создаваемые объекты, он при вызове delete вызывается, на сколько я понимаю. Далее надо думать..
Записан
AK
Новичок

Offline Offline

Сообщений: 14


Просмотр профиля
« Ответ #9 : Декабрь 15, 2020, 14:42 »

Видимо, если объявить объект, как глобальную переменную, а не на стеке, то для него придется явно вызвать деструктор
Записан
Авварон
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 3260


Просмотр профиля
« Ответ #10 : Декабрь 15, 2020, 14:52 »

нет
https://en.cppreference.com/w/cpp/language/storage_duration

Цитировать
static storage duration. The storage for the object is allocated when the program begins and deallocated when the program ends.
Only one instance of the object exists.
All objects declared at namespace scope (including global namespace) have this storage duration, plus those declared with static or extern.
See Non-local variables and Static local variables for details on initialization of objects with this storage duration.
« Последнее редактирование: Декабрь 15, 2020, 14:54 от Авварон » Записан
AK
Новичок

Offline Offline

Сообщений: 14


Просмотр профиля
« Ответ #11 : Декабрь 15, 2020, 15:14 »

То есть все статические объекты: объявленные явно как static, либо объявленные вне функций будут уничтожены с вызовом деструктора при завершении программы? В ссылке про вызов деструктора не написано явно, но видимо, так.
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Декабрь 18, 2020, 07:36 »

Не вижу примера прямого вызова деструктора. А какой был порыв любознательности, желания все изучить! И сразу потух, и куда все делось?  Улыбающийся
Записан
tux
Global Moderator
Бывалый
*****
Offline Offline

Сообщений: 404



Просмотр профиля
« Ответ #13 : Декабрь 18, 2020, 11:43 »

Деструктор вызовется далеко не всегда. Можно просто вставить тот же qDebug в саму функцию деструктора и поиграться.
Записан

RedDog
Частый гость
***
Offline Offline

Сообщений: 221


Просмотр профиля
« Ответ #14 : Декабрь 18, 2020, 13:52 »

Деструктор вызовется далеко не всегда. Можно просто вставить тот же qDebug в саму функцию деструктора и поиграться.
Вот плавно подходим к первому вопросу собеседования "зачем нужен виртуальный деструктор"  Улыбающийся
Записан
Страниц: [1] 2 3   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.115 секунд. Запросов: 23.