Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.85/13: Рейтинг темы: голосов - 13, средняя оценка - 4.85
Заблокирован
1

Исключительные ситуации (повторный вызов деструктора)

05.06.2015, 15:22. Показов 2346. Ответов 59
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Всем привет !

Подскажите пожалуйста , почему повторно вызываются деструкторы класса A,B,C?

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
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
#include <stdio.h>
#include <conio.h>
 
class Ana
 
{
    int x;
 
public:
 
    Ana(int c); 
 
    ~Ana() {}
    
    int ghf() const {return x;}
 
    class A 
    
    { 
    
    public: 
        
        A() {printf("\nKONSTRUKTOR A %p\n",this);}
 
        ~A() {printf("\nDESTRUKTOR A %p\n",this);}
    };
 
    class B : public A 
    
    {
    
    public: 
        
        B() {printf("\nKONSTRUKTOR B %p\n",this);}
 
        ~B() {printf("\nDESTRUKTOR B %p\n",this);}
    };
 
    class C : public B 
    
    {
    
    public: 
        
        C() {printf("\nKONSTRUKTOR C %p\n",this);}
 
        ~C() {printf("\nDESTRUKTOR C %p\n",this);}
    };
};
 
Ana :: Ana(int c) :
 
x(c)
 
{
    if(c == 0) throw B();
 
    if(c < 0) throw A();
 
    if(c > 10) throw C();
}
 
int main()
 
{
    try
 
    {
        Ana s(11);
 
        printf("\n-------- %d\n",s.ghf());
    }
 
 
    catch (Ana :: C)
 
    {
        printf("\n****** c > 10\n");
    }
 
    catch (Ana :: B)
 
    {
        printf("\n****** c == 0\n");
    }
 
 
    catch (Ana :: A)
 
    {
        printf("\n****** c < 0\n");
    }
        
 
        getch();
 
        return 0;
}
Миниатюры
Исключительные ситуации (повторный вызов деструктора)  
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
05.06.2015, 15:22
Ответы с готовыми решениями:

Повторный вызов деструктора
{ bar b; b.~bar(); } В данном примере деструктор bar вызовется дважды. Как у уже удаленного...

Повторный вызов деструктора для объекта
Здравствуйте! К сожалению, я пока не умею пользоваться отладчиком для анализа работы программ,...

Исключительные ситуации
Функция должна выполнять проверку параметров, передаваемых и генерировать исключения в случае...

Исключительные ситуации
Почему программа не работает?? Исключительная ситуация возникающая при деление на нуль....

59
Заблокирован
06.06.2015, 15:39  [ТС] 21
Author24 — интернет-сервис помощи студентам
почему же тогда вызвался нижний уровень копирования (((( ?
0
Неэпический
17870 / 10635 / 2054
Регистрация: 27.09.2012
Сообщений: 26,737
Записей в блоге: 1
06.06.2015, 15:45 22
Цитата Сообщение от castaway Посмотреть сообщение
Не поверю.
А была тема на форуме. В студии наблюдался фантомный вызов деструкторов. Сейчас поищу
1
Заблокирован
06.06.2015, 16:14  [ТС] 23
у меня же Microsoft Visual C++ 6.0
0
Заблокирован
18.02.2016, 17:16  [ТС] 24
Добрый день !

Меня интересует такой вопрос.

В области try пишу
C++
1
A *a = new A(-45);
при таком аргументе я принудительно бросаю исключение в конструкторе.

C++
1
2
cout<<"Конструктор "<<this<<endl;
    if (a<0) throw a;
будет ли при этом утечка памяти ?
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
37
38
39
40
41
42
43
#include <iostream>
using namespace std;
 
class A
{
    int x;
public:
    A(int a) 
    {
    cout<<"Конструктор "<<this<<endl;
    if (a<0) throw a;
        else x = a;
    }
    ~A() 
    {
        cout<<"Деструктор "<<this<<endl;
    }
    int get() const {return x;}
    void exception() const {throw 1;} 
 
};
 
int main() 
{
 
    try
    {
        A *a = new A(-45);
        cout<<"x = "<<a->get()<<endl;
        //a.exception();
        delete a;
 
    }
    catch(int a)
    {
        cout<<"catch "<<a<<endl;
 
    }
 
    cout<<")))))))))))))))))))))"<<endl;    
 
    return 0;
}
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
18.02.2016, 17:40 25
Цитата Сообщение от RAFA91 Посмотреть сообщение
будет ли при этом утечка памяти ?
Нет.
1
Заблокирован
18.02.2016, 17:43  [ТС] 26
Цитата Сообщение от Tulosba Посмотреть сообщение
Нет.
все равно напряжно на душе ведь в конструктор заходим.

а если к примеру я дохожу до
C++
1
a->exception();
?
0
18842 / 9841 / 2409
Регистрация: 30.01.2014
Сообщений: 17,284
18.02.2016, 17:48 27
Цитата Сообщение от RAFA91 Посмотреть сообщение
a->exception();
Тогда будет.
1
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
18.02.2016, 17:54 28
Цитата Сообщение от RAFA91 Посмотреть сообщение
ведь в конструктор заходим.
Пока конструктор не завершился, объекта, как такового, не существует. И ответственность за освобождение памяти, в которой он пытается создаться, берет на себя реализация языка.
5.3.4/20:
If any part of the object initialization described above terminates by throwing an exception, storage has
been obtained for the object, and a suitable deallocation function can be found, the deallocation function is
called to free the memory in which the object was being constructed, after which the exception continues to
propagate in the context of the new-expression.
1
Заблокирован
19.02.2016, 12:38  [ТС] 29
Цитата Сообщение от DrOffset Посмотреть сообщение
Тогда будет.

так это что, тогда мне нужно делать A *a глобальным что-бы иметь возможность освободить память в catch ?
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
19.02.2016, 12:52 30
Цитата Сообщение от RAFA91 Посмотреть сообщение
тогда мне нужно делать A *a глобальным
Использую RAII, например std::unique_ptr, а не "голый" new.
1
Заблокирован
19.02.2016, 13:08  [ТС] 31
Цитата Сообщение от Tulosba Посмотреть сообщение
Использую RAII
если Вы про интеллектуальные указатели - то это каменный век.

они не гарантируют 100 % подтирания зада. нужно что-то думать ((((
0
18842 / 9841 / 2409
Регистрация: 30.01.2014
Сообщений: 17,284
19.02.2016, 13:14 32
Цитата Сообщение от RAFA91 Посмотреть сообщение
так это что, тогда мне нужно делать A *a глобальным что-бы иметь возможность освободить память в catch ?
Ну это варварство.
Если речь все еще про VS6, то там выбор невелик (хотя всегда можно написать нужные RAII обертки самостоятельно), но в данном конкретном случае ты можешь использовать std::auto_ptr:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <memory>
 
int main() 
{
    try
    {
        std::auto_ptr<A> a(new A(-45));
        cout <<"x = "<< a->get() << endl;
        a->exception();
        // delete не нужен
    }
    catch(int a)
    {
        cout<<"catch "<<a<<endl;
    }
    return 0;
}
Только надо помнить, что auto_ptr не работает с массивами и если его копируют в какое-то место, то исходный указатель в auto_ptr обнуляется.

Добавлено через 1 минуту
Цитата Сообщение от RAFA91 Посмотреть сообщение
они не гарантируют 100 % подтирания зада. нужно что-то думать
Если вопрос стоит именно так, там тебе, вероятно, будет комфортно в каком-нибудь другом языке. Потому что С++ никогда не будет подтирать за тобой зад
1
Заблокирован
19.02.2016, 13:16  [ТС] 33
Цитата Сообщение от DrOffset Посмотреть сообщение
Если речь все еще про VS6,

уже давно 8-й поставил. да наверное надо использовать эти умные указатели чем глобалку.

тоже большая вероятность что забуду освободить.

Цитата Сообщение от DrOffset Посмотреть сообщение
Потому что С++ никогда не будет подтирать за тобой зад
значит надо везде в опасных местах использовать обертки.
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
19.02.2016, 13:21 34
Цитата Сообщение от DrOffset Посмотреть сообщение
вероятно, будет комфортно в каком-нибудь другом языке.
Или не будет вообще нигде.
Цитата Сообщение от DrOffset Посмотреть сообщение
С++ никогда не будет подтирать за тобой зад
А кто будет? Просто если речь о сборщике мусора, так эта задача, имхо, хорошо решается через RAII.
Или ты о чем-то другом?

Добавлено через 29 секунд
Цитата Сообщение от RAFA91 Посмотреть сообщение
уже давно 8-й поставил.
Прогресс однако
0
18842 / 9841 / 2409
Регистрация: 30.01.2014
Сообщений: 17,284
19.02.2016, 13:26 35
Цитата Сообщение от Tulosba Посмотреть сообщение
Или ты о чем-то другом?
Да, я о другом.
Я вообще. Будут "подтирать" языки с явно выраженными "safe" режимами.
А ждать этого от С++, в котором "мы не платим за то, что не используем", как-то странно.
0
Заблокирован
19.02.2016, 13:35  [ТС] 36
есть ли смысл использовать обертки собственной реализации. ?
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
19.02.2016, 13:40 37
Цитата Сообщение от RAFA91 Посмотреть сообщение
есть ли смысл использовать обертки собственной реализации. ?
Если не умеешь пользоваться стандартными, или они чем-то не устраивают, или их просто нет (в случае использования древнего компилятора), то смысл, как можно догадаться, есть.
0
Заблокирован
19.02.2016, 13:46  [ТС] 38
ну за стандартным надо потом ставить delete а в интеллектуальном достаточно один раз написать в деструкторе.
0
:)
Эксперт С++
4773 / 3267 / 497
Регистрация: 19.02.2013
Сообщений: 9,046
19.02.2016, 14:23 39
Цитата Сообщение от RAFA91 Посмотреть сообщение
ну за стандартным надо потом ставить delete а в интеллектуальном достаточно один раз написать в деструкторе.
Так стандартные - это и есть интеллектуальные: std::unique_ptr, std::shared_ptr.
Никакие явные delete с такими типами не нужны.
Другое дело, что ты можешь написать свой обёрточный интеллектуальный класс, и он не будет стандартным.
2
Заблокирован
19.02.2016, 16:40  [ТС] 40
какие грабли можно ждать от этой бумажки ?

C++
1
2
3
4
5
6
7
8
9
10
template <class T>
class pointer
{
T *p;
public:
pointer(T *_p) : p(_p) {}
~pointer() {delete p;}
T & operator * () const {return *p;}
T * operator -> () const {return p;}
};
в борланде мне часто помогал.

_________________________________

вроде сейчас все ок

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
int main() 
{
 
    try
    {
        pointer<A> a(new A(45));
        
        cout<<"x = "<<a->get()<<endl;
        a->exception();
        
        
 
    }
    catch(int a)
    {
        cout<<"catch "<<a<<endl;
 
    }
 
    cout<<")))))))))))))))))))))"<<endl;    
 
    return 0;
}
0
19.02.2016, 16:40
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
19.02.2016, 16:40
Помогаю со студенческими работами здесь

Исключительные ситуации
Доброго времени суток. Возникла такая проблема. Никак не могу разобраться с исключительными...

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

Исключительные ситуации
Как обработать исключительную ситуацию,когда переменная описана как int,к примеру,а вводится...

исключительные ситуации
Подскажите, как сделать переполнение в этой задаче: Создать класс для хранения обыкновенных...


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

Или воспользуйтесь поиском по форуму:
40
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru