Форум программистов, компьютерный форум CyberForum.ru
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
TierX
20 / 20 / 0
Регистрация: 28.02.2014
Сообщений: 138
#1

Возможно ли явное разрушение объекта класса? - C++

05.07.2014, 23:43. Просмотров 728. Ответов 23
Метки нет (Все метки)

Код (класс матрицы)
Кликните здесь для просмотра всего текста

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
#include <iostream>
#include <assert.h>
using namespace std;
class MATRIX_us{
private://V
    int counter;
    int row;
    int col;
    int**p;
public://CD
    MATRIX_us(int a, int b)
    {row=a;col=b;counter=0;
     p=new int*[row];
     for(int i=0;i<row;i++)
         p[i]=new int [col];
 
     for(int i=0;i<row;i++)
         for(int j=0;j<col;j++)
         p[i][j]=(11+j)+(10*i);
         cout<<"created"<<endl;}
 
    ~MATRIX_us(){
        for(int i =0;i<row;i++)
        delete []p[i];cout<<"destroyed col"<<endl;
        delete []p;   cout<<"destroyed row"<<endl;}
public://F
    void Show(int a, int b){cout << p[a][b];cout<<endl;}
    void Set(int a, int b, int c){p[a][b]=c;}
    void ShowAll(){
     for(int i=0;i<row;i++)
         for(int j=0;j<col;j++){
             cout<<p[i][j]<<' ';counter++;
             if(counter==row){cout<<endl;counter=0;}}}};
 
 
int main() {
 
    MATRIX_us a(2,2);
           //a.~MATRIX_us();  <-- ???
    system("PAUSE");
    }

Вобщем можно ли както удалить обьект класса явно? Пытался через явный вызов деструктора(с чего и началось) но класс остался полуживой.Компилятор может дальше использовать методы класса не ругаясь.
По завершению програмы вылетает:
Необработанное исключение по адресу 0x5EAE7508 (msvcr110d.dll) в удаляй1.exe: 0xC0000005: нарушение прав доступа при чтении по адресу 0xFEEEFEE2.
Без понятия что это, но явно чтото не ок. Вобщем не получаетсо. Зачем тогда предусмотрен явный вызов деструктора?

И еще интересно тот же вопрос про указатель:
1)Как инициализированый ранее указатель явно привести в нерабочюю форму (типа начального *ptr=NULL можно ли так после инициализации делать?)
2)Как удалить его.

Насколько я понимаю все обьекты/переменные/функции созданые в main идут на стек но как их оттуда удалять явно?(аля new/delete)
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
05.07.2014, 23:43
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Возможно ли явное разрушение объекта класса? (C++):

Возможно ли создание объекта шаблонного класса в функции этого класса? - C++
Доброго времени суток, уважаемые форумчане :) Мне по лабам задали задание - реализовать шаблон контейнера (множество) с операциями...

Явное создание экземпляра класса и явная специализация шаблона класса - C++
Всем добрый день! Не могу разобраться - эти две технологии дают один и тот же результат? В каких случаях применять одно и другое?...

Создание и разрушение объектов класса, исследование вызовов конструкторов и деструкторов - C++
Здравствуйте! Проверте пожалуйста код и подскажите мои ошибки. Согласно теме необходимо разобрать класс библиотека(имя – char*, автор –...

Объявление объекта класса fstream в качестве статической компоненты другого класса - C++
Доброго времени суток. Есть задание, в котором говорится &quot;...Перепишите программы из упражнений 4 и 6 таким образом, чтобы использовать...

Проверка создания объекта класса BBB из класса AAA и работа с ним - C++
#define @param2; // объявили для выяснения случая: нужен новый или использовать существующий. Class AAA { private: void...

Создание объекта класса с полем являющимся объектом другого класса - C++
Bill a; cin&gt;&gt;a;//тут я ввел с помощью перегруженного оператора ElementSpiska c; //поля у Spiska(Bill A,int,string,int) ...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Jupiter
Каратель
Эксперт С++
6554 / 3975 / 226
Регистрация: 26.03.2010
Сообщений: 9,273
Записей в блоге: 1
Завершенные тесты: 2
05.07.2014, 23:51 #2
C++
1
2
3
4
5
6
7
8
9
int main()
{
    //There is no spoon
    {
          MATRIX_us a(2,2); //spoon here
    }
    //There is no spoon
    system("PAUSE");
}
Добавлено через 1 минуту
Цитата Сообщение от TierX Посмотреть сообщение
Зачем тогда предусмотрен явный вызов деструктора?
для placement new

Добавлено через 29 секунд
Цитата Сообщение от TierX Посмотреть сообщение
1)Как инициализированый ранее указатель явно привести в нерабочюю форму (типа начального *ptr=NULL можно ли так после инициализации делать?)
C++
1
ptr = 0;
1
gray_fox
What a waste!
1520 / 1223 / 70
Регистрация: 21.04.2012
Сообщений: 2,560
Завершенные тесты: 3
05.07.2014, 23:51 #3
Цитата Сообщение от TierX Посмотреть сообщение
По завершению програмы вылетает:
потому что деструктор был вызван 2 раза: явно и неявно.
Цитата Сообщение от TierX Посмотреть сообщение
Зачем тогда предусмотрен явный вызов деструктора?
Нужно при использовании placement new
Цитата Сообщение от TierX Посмотреть сообщение
Насколько я понимаю все обьекты/переменные/функции созданые в main идут на стек но как их оттуда удалять явно?(аля new/delete)
И зачем удалять их явно? Ведь для этого по сути и придуманы деструкторы - что бы в ручную не заниматься деинициализацией.
1
DrOffset
7155 / 4296 / 972
Регистрация: 30.01.2014
Сообщений: 7,101
05.07.2014, 23:57 #4
Цитата Сообщение от TierX Посмотреть сообщение
Пытался через явный вызов деструктора(с чего и началось) но класс остался полуживой.
C++ не таков. Он не будет тебя защищать от прострела ног, рук и т.п. По стандарту обращение к данным разрушенного класса - Undefined behaviour.
Цитата Сообщение от TierX Посмотреть сообщение
По завершению програмы вылетает
Потому что деструктор вызывается второй раз. В этом суть автоматических объектов. Деструктор вызывается в конце области видимости.
Цитата Сообщение от TierX Посмотреть сообщение
Зачем тогда предусмотрен явный вызов деструктора?
Для других ситуаций. В частности вот для этого.
Цитата Сообщение от TierX Посмотреть сообщение
Насколько я понимаю все обьекты/переменные/функции созданые в main идут на стек но как их оттуда удалять явно?(аля new/delete)
На стек идут автоматические объекты. Удалять их явно оттуда не нужно. Объект живет в своей scope, в конце scope он автоматически разрушается.
Цитата Сообщение от TierX Посмотреть сообщение
типа начального *ptr=NULL можно ли так после инициализации делать?
Если до этого был new, то обязательно должен быть delete. Иначе, присвоив NULL значению указателя, мы потеряем адрес выделенной памяти и будет утечка.
Цитата Сообщение от TierX Посмотреть сообщение
Как удалить его.
Что именно нужно удалить? Указатель или объект на который он указывает?
1
TierX
20 / 20 / 0
Регистрация: 28.02.2014
Сообщений: 138
06.07.2014, 00:11  [ТС] #5
В том то и дело , что он по идее недолжен был вызываться второй раз неявно. Так как обьект должен был разрушиться. Отсюда следует, что одного деструктора недостаточно для уничтожения обьекта -> чегото не хватает->можно ли это (то чего не хватает) явно вызывать?

Ну как зачем... Чтобы удалять ненужные обьекты которые висят без дела после отработки. Создал обьект кинул в функцию->функция отработала -> в другую-> стал не нужен-> нужно удлаить. Так?
0
DrOffset
7155 / 4296 / 972
Регистрация: 30.01.2014
Сообщений: 7,101
06.07.2014, 00:16 #6
Цитата Сообщение от TierX Посмотреть сообщение
В том то и дело , что он по идее недолжен был вызываться второй раз неявно.
Должен.
Цитата Сообщение от TierX Посмотреть сообщение
Отсюда следует, что одного деструктора недостаточно для уничтожения обьекта -> чегото не хватает->можно ли это (то чего не хватает) явно вызывать?
Достаточно. Вывод неверный.
Цитата Сообщение от TierX Посмотреть сообщение
Чтобы удалять ненужные обьекты которые висят без дела после отработки.
Ну так он и так удалится, в конце scope (области видимости), любой. В первом ответе, был создан вложенный scope, как раз для демонстрации удаления в середине main.
1
TierX
20 / 20 / 0
Регистрация: 28.02.2014
Сообщений: 138
06.07.2014, 00:17  [ТС] #7
Что именно нужно удалить? Указатель или объект на который он указывает?
Сам указатель.
Блин чото я не врублю... Если я создал обект в начале main , то он удалиться по идее только по завершению main. Значит он будет жить всё время. Но он мне уже не нужен в средине программы допустим.Могу ли я его удалить или как?
0
gray_fox
What a waste!
1520 / 1223 / 70
Регистрация: 21.04.2012
Сообщений: 2,560
Завершенные тесты: 3
06.07.2014, 00:17 #8
Цитата Сообщение от TierX Посмотреть сообщение
В том то и дело , что он по идее недолжен был вызываться второй раз неявно.
Должен - по выходу из области видимости для всех объектов вызывается деструктор в обратном порядке их (объектов) объявления (a la стек).
Цитата Сообщение от TierX Посмотреть сообщение
у как зачем... Чтобы удалять ненужные обьекты которые висят без дела после отработки. Создал обьект кинул в функцию->функция отработала -> в другую-> стал не нужен-> нужно удлаить.
Тогда ограничивай область видимости (см. пост Jupiter); либо можно написать функцию деинициализации (так же разместив её вызов в деструкторе) так, что бы при повторном вызове она ничего не делала, и дёргать её, когда захочется, но это не "C++-way".
1
DrOffset
7155 / 4296 / 972
Регистрация: 30.01.2014
Сообщений: 7,101
06.07.2014, 00:20 #9
Цитата Сообщение от TierX Посмотреть сообщение
Сам указатель.
Сам указатель в данной ситуации - автоматический объект. Соответственно, удалится он в конце области видимости. О чем уже писалось
1
TierX
20 / 20 / 0
Регистрация: 28.02.2014
Сообщений: 138
06.07.2014, 00:26  [ТС] #10
Да я понимаю что они сами уничтожаються по окончанию области видимости. А можно ли их удять явно самому до окончания области видимости. О чом уже и спрашивалось
Если же деструктор вызываеться второй раз - значит явный вызов дестрктора не уничтожил обьект. Явный вызов деструктора != окончанию области видимости.
0
gray_fox
What a waste!
1520 / 1223 / 70
Регистрация: 21.04.2012
Сообщений: 2,560
Завершенные тесты: 3
06.07.2014, 00:35 #11
Цитата Сообщение от TierX Посмотреть сообщение
Если же деструктор вызываеться второй раз - значит явный вызов дестрктора не уничтожил обьект.
И откуда такой вывод? Вне зависимости от того, что было вызвано\ещё чего, компилятор встроит вызов деструктора в конце области видимости для всех созданных в этой области видимости объектов - таков дизайн языка, этого не поменять.
1
DrOffset
7155 / 4296 / 972
Регистрация: 30.01.2014
Сообщений: 7,101
06.07.2014, 00:38 #12
Цитата Сообщение от TierX Посмотреть сообщение
А можно ли их удять явно самому до окончания области видимости. О чом уже и спрашивалось
Нельзя. Если нужно полный контроль за временем жизни объекта, то нужно использовать динамическое выделение памяти или\и placement new (было по ссылке выше).
Цитата Сообщение от TierX Посмотреть сообщение
Если же деструктор вызывается второй раз - значит явный вызов дестрктора не уничтожил обьект.
Уничтожил. Именно поэтому программа упала. Нельзя уничтожать второй раз то, что уже уничтожено. А вызывается он согласно модели данных, которая принята в языке. Никакой рантайм анализ как в управляемых языках не проводится на предмет того вызвал ли программер сам деструктор или нет. Это добавило бы ненужный оверхед, который не согласуется с идеологий языка ("не платим за то, что не используем").
1
TierX
20 / 20 / 0
Регистрация: 28.02.2014
Сообщений: 138
06.07.2014, 00:38  [ТС] #13
Видимо предусмотреного стандартного способа нету... Может конечно я и глупые вопросы задаю но по мне так гораздо проще удалить обьект явно, чем кутать его в скобы для неявного удаления.
Спасибо за ответы. Хоть в душе я остался не доволен
0
gray_fox
What a waste!
1520 / 1223 / 70
Регистрация: 21.04.2012
Сообщений: 2,560
Завершенные тесты: 3
06.07.2014, 00:42 #14
Цитата Сообщение от TierX Посмотреть сообщение
Видимо предусмотреного стандартного способа нету... Может конечно я и глупые вопросы задаю но по мне так горазда проще удалить обьект явно, чем кутать его в скобы для неявного удаления.
Так напиши метод деинициализации и дёргай его (прмерно так сделано в std::fstream, например), это не сложно:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class MATRIX_us {
 
   // ...
 
   void destroy() {
      if (p) {
         for (int i = 0; i != row; ++i) {
            delete[] p[i];
         }
         delete[] p;
         p = 0;
      }
   }
 
   ~MATRIX_us() {
      destroy();
   }
};
1
DrOffset
7155 / 4296 / 972
Регистрация: 30.01.2014
Сообщений: 7,101
06.07.2014, 00:42 #15
Цитата Сообщение от TierX Посмотреть сообщение
по мне так горазда проще удалить обьект явно, чем кутать его в скобы для неявного удаления.
Не надо его кутать Это был просто пример. Нужно писать программу так, чтобы все объекты выделялись и освобождаись в свое время, время это распределять через области видимости. Короче говоря, декомпозиция и принцип "разделяй и властвуй". Если фигачить все сплошной простыней и потом сетовать, что объект нельзя удалить в середине этой простыни, то тут проблема гораздо глубже.
1
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
06.07.2014, 00:42
Привет! Вот еще темы с ответами:

Использование объекта одного класса при создании нового класса - C++
Добрый вечер. У меня такая проблема. Есть готовый класс L2 - список, на его основе нужно создать дек. Я поступил так: в приватной части...

Ошибка компиляции (преобразование объекта класса в объект другого класса) - C++
Друзья, добрый день! Не могу понять почему выдается ошибка компиляции... Прога преобразует доллары США в старые Британские фунты. Но...

Указатель на объект базового класса и адрес объекта производного класса - C++
Пример кода: class Class1 { public: Class1(int x) { j = new int; *j = x; } ~Class1() {delete j;}

Реализовать оператор= для присваивания объекта класса-потомка объекту базового класса - C++
Есть два класса A и B, причем класс B является потомком A. Как реализовать следующее: obj_A = obj_B и obj_B = obj_A? Добавлено через 9...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
06.07.2014, 00:42
Ответ Создать тему
Опции темы

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