crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Гарантия на деструктор.
call_me_Frank
  опции профиля:
сообщение 21.11.2013, 17:26
Сообщение #1


Студент
*

Группа: Участник
Сообщений: 73
Регистрация: 20.10.2010
Пользователь №: 2129

Спасибо сказали: 0 раз(а)




Репутация:   0  


Господа, есть вопрос. Насколько можно быть уверенным в том, что при закрытии приложения (не аварийном) будут выполнены все команды в деструкторе объекта?

Пример:
int main(int argc, char *argv[]){
    //

    QApplication a(argc, argv);
    //QApplication::setQuitOnLastWindowClosed(false);

    // GUI
    MainWindow w;
    w.show();

    Mainy *my = new Mainy(&a);

    return a.exec();
}


Mainy - класс-наследник от QObject, его деструктор:
Mainy::~Mainy(){
    //

    qDebug() << "~Mainy() ";
}


сообщение выводится в 50% случаев закрытия.

я не знаю, как работает дебаг, но у меня из-за этого серьезные опасения насчет того, что половина инструкций внутри деструктора может просто не выполниться...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 21.11.2013, 18:56
Сообщение #2


Профессионал
*****

Группа: Модератор
Сообщений: 1594
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


деструктор выполняется всегда, когда объект уничтожается. при выходе за область видимости объект уничтожается. тут нет никаких вариантов и неясностей.
но при наследовании деструктор должен быть виртуальным. иначе он может и не вызываться.
а у тебя ещё нет вызова delete. раз ты его создал (new), то должен быть и delete.

Сообщение отредактировал Iron Bug - 21.11.2013, 18:58
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
call_me_Frank
  опции профиля:
сообщение 22.11.2013, 7:26
Сообщение #3


Студент
*

Группа: Участник
Сообщений: 73
Регистрация: 20.10.2010
Пользователь №: 2129

Спасибо сказали: 0 раз(а)




Репутация:   0  


Хорошо, деструктор вызывается в 100% случаев без исключений. Но вывод функции qDebug() случается далеко не каждый раз. Почему? Я предполагаю, что вызвав qDebug(), программа в итоге завершается быстрее, чем производится сам вывод. Все бы ничего - черт с ним с дебагом, но меня беспокоит то, что вероятно есть и другие функции, которые будут вести себя подобным же образом. И как в таком случае проследить 100-процентное выполнение всех до полного завершения? Работать в режиме отладки возможности нет, т.к. использую либы, которые этот режим не поддерживают и портят всю малину.

Насчет delete. В данном примере я рассчитываю на то, что об этом позаботится родитель моего объекта (&a). Или я не прав? В таком случае, где же разместить delete my, чтобы он вызывался при закрытии программы? Делать для этого отдельный класс с соотв. слотом неохота...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 22.11.2013, 8:28
Сообщение #4


Профессионал
*****

Группа: Модератор
Сообщений: 1594
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Цитата(call_me_Frank @ 22.11.2013, 10:26) *
В данном примере я рассчитываю на то, что об этом позаботится родитель моего объекта (&a).

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

если нет понятного места, где нужно удаление объекта, используются автоматические указатели.

Сообщение отредактировал Iron Bug - 22.11.2013, 8:29
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 23.11.2013, 15:50
Сообщение #5


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9656
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


Цитата(Iron Bug @ 21.11.2013, 20:56) *
а у тебя ещё нет вызова delete. раз ты его создал (new), то должен быть и delete.
там наследование от QObject, а он (и его потомки) сами удаляют своих детей. Под детьми понимаются объекты созданные с указанием родителя, конструктор QObject:
QObject ( QObject * parent = 0 )

Пример в коде:
SomeClass *parent = new SomeClass(0); // 0 - для примера, что явно нет родителя
SomeClass *obj = new SomeClass(parent); // есть родитель

В таком коде obj явно удалять не нужно, это сделает деструктор parent-а.
А вот parent удалять нужно самому.

Обычно код на Qt выглядит так:

int main (...)
{
    SomeClass parent(); // Создан на стеке, чтобы руками не удалять

}

// ....

SomeClass::SomeClass(...)
{
    OtherClass *object = new OtherClass(this); // передан в качестве родителя экземпляр ЭТОГО класса
}


Цитата(call_me_Frank @ 21.11.2013, 19:26) *
сообщение выводится в 50% случаев закрытия.

Цитата(Iron Bug @ 21.11.2013, 20:56) *
деструктор выполняется всегда, когда объект уничтожается. при выходе за область видимости объект уничтожается. тут нет никаких вариантов и неясностей.
по моей практике, если выходим за область видимости при выходе из функции main, то объекты непосредственно созданные в ней, действительно могут убиваться каким-то иным способом и деструктор не вызывается (и довольно нестабильно это).
При этом код может не использовать ни каких библиотек (например, Qt).

С чем это связано я до сих пор не знаю.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 23.11.2013, 16:57
Сообщение #6


Профессионал
*****

Группа: Модератор
Сообщений: 1594
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Цитата(Litkevich Yuriy @ 23.11.2013, 18:50) *
по моей практике, если выходим за область видимости при выходе из функции main, то объекты непосредственно созданные в ней, действительно могут убиваться каким-то иным способом и деструктор не вызывается (и довольно нестабильно это).
При этом код может не использовать ни каких библиотек (например, Qt).

С чем это связано я до сих пор не знаю.

ну тогда всё понятно: QApplication удаляется уже после выхода из main. соответственно, на этом этапе ничего от программы не остаётся. обращения к ресурсам программы ошибочны. а если это срабатывает, то только потому, что система ещё не успела затереть память.

Сообщение отредактировал Iron Bug - 23.11.2013, 16:57
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Litkevich Yuriy
  опции профиля:
сообщение 23.11.2013, 20:08
Сообщение #7


разработчик РЭА
*******

Группа: Сомодератор
Сообщений: 9656
Регистрация: 9.1.2008
Из: Тюмень
Пользователь №: 64

Спасибо сказали: 807 раз(а)




Репутация:   94  


К стати, нашёл у себя во фрагментах кода (заготовочках), такую штуку:
int main (...)
{
    int res = 0;
    {
        QApplication a(argc, argv);
        ...
        res = a.exec();
     }
     return res;
}
т.е. работать должно так: как только Qt приложение заканчивает работать, то QApplication::exec(), возвращает управление (цикл обработки событий прерывается). Затем происходит выход из области видимости (фигурные скобки), но функция main ещё не завершилась.
Этот трюк позволяет отработать всем нужным/полезным деструкторам до завершения функции main.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 24.11.2013, 9:33
Сообщение #8


Профессионал
*****

Группа: Модератор
Сообщений: 1594
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


Цитата(Litkevich Yuriy @ 23.11.2013, 23:08) *
К стати, нашёл у себя во фрагментах кода (заготовочках), такую штуку:

да, это, безусловно, будет работать. область видимости закрывается раньше, чем завершается main и уничтожаются ресурсы программы.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 29.1.2020, 23:47