Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
Рейтинг 5.00/4: Рейтинг темы: голосов - 4, средняя оценка - 5.00
29 / 29 / 16
Регистрация: 06.03.2013
Сообщений: 159
1

Почему вызывается деструктор?

28.07.2016, 11:32. Просмотров 781. Ответов 14
Метки нет (Все метки)

Доброго времени суток. Написал такой код:
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
25
26
27
28
29
struct O
{
    virtual ~O()
    {    
        cout << "hey";
    }
};
struct Ex : public O
{
    Ex()
    {    
    }
    ~Ex()
    {
        throw(1);
    }
};
int _tmain(int argc, _TCHAR* argv[])
{
    try
    {
        Ex obj;            
    }        
    catch(int err)
    {
    }    
    
    return 0;
}
как мне казалось, вызов исключения в деструкторе производного класса, должен вызвать ситуацию, когда деструктор базового класса вызван не будет. однако, "hey" пишется. MSVS 2008.

Более того. Загнал этот код в онлайн компилятор. Если поставить стандарт 98, то деструктор вызывается. Если х11 или х14, то не вызывается.

Почему так? Ведь по выходу из области видимости разрушается переменная obj и вызывается её деструктор. Сначала деструктор класса Ex, после которого должен быть вызван деструктор класса O. Но вызывается исключение и до деструктора O дело дойти не должно. В чём я ошибаюсь / чего не вижу?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
28.07.2016, 11:32
Ответы с готовыми решениями:

Почему не вызывается деструктор?
Всем доброго времени суток! Подскажите пожалуйста - почему не вызывается деструктор при...

Объясните почему вызывается деструктор
Вот код char* ConjunctionLots(ArrayLot firstLot, ArrayLot secondLot, ArrayLot thirdLot) {...

Почему деструктор вызывается два раза
Всем привет. Есть код, для примера #include &lt;vector&gt; using namespace std; struct AA { int n;...

Почему виртуальный деструктор вызывается дважды?
Непонятно: #include &lt;iostream&gt; #include &lt;conio.h&gt; #include&lt;string&gt; using namespace std;...

14
129 / 101 / 58
Регистрация: 26.10.2013
Сообщений: 306
28.07.2016, 11:50 2
Никогда не позволяйте исключениям покидать деструктор. Никогда.

За подробностями к Скотту Мейерсу.
0
29 / 29 / 16
Регистрация: 06.03.2013
Сообщений: 159
28.07.2016, 12:03  [ТС] 3
Так не. Я вроде слышал, что не стоит позволять. Но это что UB? Пример чисто учебный, чтобы разобраться как вообще обстоят дела.
0
129 / 101 / 58
Регистрация: 26.10.2013
Сообщений: 306
28.07.2016, 12:18 4
В C++11 и 14 все деструкторы неявно помечены как noexcept. Если исключение покидает деструктор, программа аварийно завершается.

Не помню про 98, там скорее всего деструктор неявно помечен как throw().

Думаю, этого достаточно чтобы понять, что ваш код не имеет смысла.
0
Миниатюры
Почему вызывается деструктор?  
29 / 29 / 16
Регистрация: 06.03.2013
Сообщений: 159
28.07.2016, 12:30  [ТС] 5
Спасибо, про noexcept я почитал. Теперь понял. Также понял примерно чем грозит "покидание исключением деструктора". Но мне так и не ясно, почему в 98 вызывается деструктор базового класса. throw 1, заставляет искать первый блок try-catch. находит. и что, пытается уничтожить базовую часть объекта obj? то есть получается, что для одной переменной вызывается деструтор два раза?
0
129 / 101 / 58
Регистрация: 26.10.2013
Сообщений: 306
28.07.2016, 12:40 6
Цитата Сообщение от xTr1m Посмотреть сообщение
и что, пытается уничтожить базовую часть объекта obj
catch?
0
823 / 247 / 34
Регистрация: 27.07.2016
Сообщений: 497
Записей в блоге: 1
28.07.2016, 12:43 7
xTr1m,
An object of any storage duration whose initialization or destruction is terminated by an exception will have destructors executed for all of its fully constructed subobjects (excluding the variant members of a union-like class), that is, for subobjects for which the principal constructor (12.6.2) has completed execution and the destructor has not yet begun execution.
0
29 / 29 / 16
Регистрация: 06.03.2013
Сообщений: 159
28.07.2016, 12:54  [ТС] 8
HelicopterK52, спасибо. Мне всегда казалось, что исключение в деструкторе черевато прежде всего тем, что не будут вызваны деструкторы базовых классов. А получается, что в 98ом деструкторы базовых вызываются, а в 11ом и вовсе программа завершается принудительно
0
823 / 247 / 34
Регистрация: 27.07.2016
Сообщений: 497
Записей в блоге: 1
28.07.2016, 13:12 9
xTr1m, в c++03 исключение в деструкторе приводило к std::terminate, если деструтор этот был вызван в процессе раскрутки стека, т.е. когда уже "летит" другое исключение.
0
29 / 29 / 16
Регистрация: 06.03.2013
Сообщений: 159
28.07.2016, 13:28  [ТС] 10
Так в моём случае, деструктор вызывается просто. его вызов - это просто окончание действия переменной. но ведь всё равно аварийно закрывается
0
823 / 247 / 34
Регистрация: 27.07.2016
Сообщений: 497
Записей в блоге: 1
28.07.2016, 13:29 11
Цитата Сообщение от xTr1m Посмотреть сообщение
но ведь всё равно аварийно закрывается
В c++03 - не завершится:
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
25
26
27
28
29
30
31
32
33
34
35
36
#include <iostream>
using namespace std;
 
struct O
{
    virtual ~O()
    {    
        cout << "hey" << endl;
    }
};
struct Ex : public O
{
    Ex()
    {    
    }
    ~Ex()
    {
        throw(1);
    }
};
int main()
{
    try
    {
        Ex obj; 
        //throw 3.4;//вот с этим закроется аварийно
    }        
    catch(int err)
    {
        cout << "catch(int)" << endl;
    }   
    catch(...)
    {
    }
    cout << "end of main" << endl;
}
http://rextester.com/VDG67565

Начиная с c++11, деструкторы по дефолту являются noexcept,
вылет исключения из noexcept функции (не обязательно из деструктора),
приводит к вызову std::terminate.
0
29 / 29 / 16
Регистрация: 06.03.2013
Сообщений: 159
28.07.2016, 13:34  [ТС] 12
Всё, кажется я окончательно разобрался. Вопросов пока нет))) Голову можно сломать. Неужели в реальной жизни так часто встречаются такие ситуации? Или просто это тема из разряда "если программист это знает, то когда-нибудь, один раз в жизни ему попадется нечто подобное и он будет знать, куда копать" ?
0
823 / 247 / 34
Регистрация: 27.07.2016
Сообщений: 497
Записей в блоге: 1
28.07.2016, 13:37 13
Цитата Сообщение от xTr1m Посмотреть сообщение
Неужели в реальной жизни так часто встречаются такие ситуации?
Какие именно? Вызов исключений в деструкторах? Тут сразу смерть приходит, так что забывать в деструкторе о проверках не нужно.
Цитата Сообщение от xTr1m Посмотреть сообщение
и он будет знать, куда копать?
В принципе, он и так должен знать куда копать.
0
Эксперт С++
8330 / 3886 / 843
Регистрация: 15.11.2014
Сообщений: 8,787
28.07.2016, 14:41 14
Цитата Сообщение от xTr1m Посмотреть сообщение
Неужели в реальной жизни так часто встречаются такие ситуации?
нет)
в реально жизни никто эксепшены и деструкторах не кидает)

а если даже и кидают,
то в самом деструкторе ставиццо ловушка,
которая не дает эксепшенам просочиццо наружу.

и как бе проблем никаких)
0
29 / 29 / 16
Регистрация: 06.03.2013
Сообщений: 159
28.07.2016, 14:55  [ТС] 15
ну я понял. всем большое спасибо
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
28.07.2016, 14:55

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

Почему при помещении объекта в list вызывается конструктор и деструктор?
Нужна помощь опытного программиста. Не могу понять почему при помещение объекта в list вызывается...

При создании класса конструктор вызывается 2 раза, затем вызывается деструктор о_О
Вот такой кодclass A { public: A(){} virtual ~A(){} }; class C { public:

Не вызывается деструктор
_Здравствуйте. Я новичок в программировании, сейчас изучаю самостоятельно С++ по книге Джесса...

Деструктор не вызывается
В одном классе я создаю объект, и если проверку не проходит, я его возвращаю в другой метод, дабы...


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

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.