Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> В какой области память расположен объект? Создан оператором new или нет 
:(
    Опции темы
CEMEH
Дата 6.7.2006, 12:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 6.7.2006
Где: Украина, Харьков

Репутация: нет
Всего: нет



Смотрел я топики, где обсуждается 'delete this', но ответа на свой вопрос так и не нашел.
Есть объект, который должен удалять сам себя при условии что он создан динамически.
В противном случае он себя чистит и все, а память освобождается при удалении родительского объекта.
Пример:

Код

class Window
{
    public:
        Window(Window* parent=0) : _parent(parent) { if(_parent) _parent->insert(this); }
        ~Window() { destroy(); }
        void destroy() { /* ... Освобождаем ресурсы системы ... */; clean(); }

    protected:
        void insert(Window* w) { /* Добавляем в 'childs' */}
        void remove(Window* w) { /* Удаляем из 'childs' */}

    private:
        bool isDynamic() { /* Как определить динамический ли 'this'? */ }
        void clean()
        {
            if(!childs.empty())
                for_each(wlist.begin(), wlist.end(), mem_fun(&Window::clean));
            if(_parent)
                _parent->remove(this); 
            _parent = 0;
            /*Вот это место*/
            if(isDynamic()) delete this;
        }
        Window* _parent;
        list<Window*> childs;
};


Т.е. если не осуществлять проверку то деструктор объекта созданного в автоматической памяти будет вызван дважды
delete this и компилятором. Как это решить?  

Это сообщение отредактировал(а) CEMEH - 6.7.2006, 12:58
PM MAIL WWW ICQ   Вверх
Daevaorn
Дата 6.7.2006, 14:25 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Цитата(CEMEH @  6.7.2006,  13:48 Найти цитируемый пост)
Т.е. если не осуществлять проверку то деструктор объекта созданного в автоматической памяти будет вызван дважды
delete this и компилятором. Как это решить?  

Запретить создавать объект на стеке. Переносимого решения, как определить в какой памяти объект - не существует. Delete this - плохой стиль проектирования (не всегда правда, но в твоём случае точно) 
PM MAIL WWW   Вверх
likehood
Дата 6.7.2006, 15:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


666
**


Профиль
Группа: Участник
Сообщений: 536
Регистрация: 21.12.2005

Репутация: 8
Всего: 24



А зачем тебе вообще нужен вызов delete this? Ты что, явно вызываешь деструктор ~Window()? 
PM MAIL   Вверх
Rockie
Дата 6.7.2006, 20:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1143
Регистрация: 23.4.2006

Репутация: 8
Всего: 31



Цитата(CEMEH @  6.7.2006,  12:48 Найти цитируемый пост)
Т.е. если не осуществлять проверку то деструктор объекта созданного в автоматической памяти будет вызван дважды
delete this и компилятором. Как это решить?  


imho после первого delete присваивать указателю NULL. если потом будет еще раз вызван delete, то по крайней мере ничего плохого не случится.
 


--------------------
Чтобы иметь большой гардероб - надо иметь большой гардероб.
PM   Вверх
Earnest
Дата 7.7.2006, 06:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Экс. модератор
Сообщений: 5962
Регистрация: 17.6.2005
Где: Рязань

Репутация: 53
Всего: 183



Цитата(Daevaorn @  6.7.2006,  15:25 Найти цитируемый пост)
Запретить создавать объект на стеке. Переносимого решения, как определить в какой памяти объект - не существует. Delete this - плохой стиль проектирования (не всегда правда, но в твоём случае точно)  

Поддерживаю. Пересмотри дизайн. 


--------------------
...
PM   Вверх
CEMEH
Дата 7.7.2006, 09:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 6.7.2006
Где: Украина, Харьков

Репутация: нет
Всего: нет



Цитата(Daevaorn @  6.7.2006,  14:25 Найти цитируемый пост)
Запретить создавать объект на стеке. Переносимого решения, как определить в какой памяти объект - не существует. Delete this - плохой стиль проектирования (не всегда правда, но в твоём случае точно) 

Как запретить?
Если создано 1000 окон, то спрятав окно из close() я [B]не[/B ]повышу производительность.
Нужно память освободить.
И почему же в моем случае - точно? Кинь линк, где увидеть хороший случай!!!

Цитата(baronp @  6.7.2006,  15:14 Найти цитируемый пост)
А зачем тебе вообще нужен вызов delete this? Ты что, явно вызываешь деструктор ~Window()? 

Да. А что из кода не видно?
Ну пусть это будет не 'delete this' а 'this->~Window()', разницы нет никакой.

Цитата(Rockie @  6.7.2006,  20:09 Найти цитируемый пост)
imho после первого delete присваивать указателю NULL. если потом будет еще раз вызван delete, то по крайней мере ничего плохого не случится

Попробуй this присвоить NULL. Посмотрел бы я на это :-)
 
PM MAIL WWW ICQ   Вверх
likehood
Дата 7.7.2006, 09:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


666
**


Профиль
Группа: Участник
Сообщений: 536
Регистрация: 21.12.2005

Репутация: 8
Всего: 24



Цитата(CEMEH @  7.7.2006,  10:39 Найти цитируемый пост)
Да. А что из кода не видно?

В твоем коде нет явного вызова деструктора.

Да и зачем явно вызывать деструктор в твоем случае? 
PM MAIL   Вверх
Daevaorn
Дата 7.7.2006, 11:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Комодератор
Сообщений: 2155
Регистрация: 29.11.2004
Где: Москва

Репутация: 51
Всего: 70



Цитата(CEMEH @  7.7.2006,  10:39 Найти цитируемый пост)
Как запретить?

Закрой все конструкторы, сдалай фабрику или 
Код
Window* Window::create(/*...*/)

Но это всё не очень хорошо.
Второй вариант: сделай пустой деструктор (или только удаление childs, хотя умные указатели предпочтительней), window::remove пусть удалеят окно. Значит клиентскому коду для удалния уже ненужного окна надо вызвать всего лишь window::clean(). Надеюсь идея ясна.
Цитата(CEMEH @  7.7.2006,  10:39 Найти цитируемый пост)
И почему же в моем случае - точно? Кинь линк, где увидеть хороший случай!!!

Посмотри boost::shared_count, там delete this является частью элегантного решения по делегации удаления объекта сечтчика по сути пользовательскому класса. 
PM MAIL WWW   Вверх
Rockie
Дата 7.7.2006, 11:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1143
Регистрация: 23.4.2006

Репутация: 8
Всего: 31



а если

http://www.codeguru.com/forum/archive/inde...p/t-179284.html

Цитата

NMTop40
04-04-2006, 03:20 AM
Once you have deleted a pointer the memory is free to be used again. Even if you know the heap space has not been reallocated, attempting to delete the same pointer again is not a safe action - the heap manager is not required to "ignore" the delete. (Unlike deleting a NULL-pointer which is guaranteed to be safe).

If your class is going to have a delete this then it should have a private or protected destructor.
Bornish
04-04-2006, 04:08 AM
If your class is going to have a delete this then it should have a private or protected destructor.Why is that?
NMTop40
04-04-2006, 04:16 AM
That will prevent your class from being created on the stack or being deleted in any other manner than calling the function that hits the self-destruct button.
Bornish
04-04-2006, 09:16 AM
That will prevent your class from being created on the stack or being deleted in any other manner than calling the function that hits the self-destruct button.Then, it should have only a private destructor. A protected one would allow deriving from it, and such derived class could be also created on the stack. ;)
vBulletin v3.0.12, Copyright ©2000-2006, Jelsoft Enterprises Ltd.
 


--------------------
Чтобы иметь большой гардероб - надо иметь большой гардероб.
PM   Вверх
CEMEH
Дата 10.7.2006, 11:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 3
Регистрация: 6.7.2006
Где: Украина, Харьков

Репутация: нет
Всего: нет



Всем спасибо!
 smile  
PM MAIL WWW ICQ   Вверх
Rockie
Дата 10.7.2006, 12:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
***


Профиль
Группа: Завсегдатай
Сообщений: 1143
Регистрация: 23.4.2006

Репутация: 8
Всего: 31



CEMEH, а как решили проблему?
 


--------------------
Чтобы иметь большой гардероб - надо иметь большой гардероб.
PM   Вверх
Alca
Дата 28.11.2009, 20:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 7
Всего: 50



Цитата

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

Меня тоже интересует решение. 


--------------------
PM WWW ICQ Skype Jabber   Вверх
Alca
Дата 29.11.2009, 10:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 3993
Регистрация: 14.6.2006

Репутация: 7
Всего: 50



Цитата

Запретить создавать объект на стеке

Как?


--------------------
PM WWW ICQ Skype Jabber   Вверх
likehood
Дата 29.11.2009, 10:58 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


666
**


Профиль
Группа: Участник
Сообщений: 536
Регистрация: 21.12.2005

Репутация: 8
Всего: 24



Цитата(Alca @  29.11.2009,  10:26 Найти цитируемый пост)
Как? 


Цитата(Daevaorn @  6.7.2006,  14:25 Найти цитируемый пост)
Переносимого решения, как определить в какой памяти объект - не существует.


PM MAIL   Вверх
Alexeis
Дата 29.11.2009, 11:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Амеба
Group Icon


Профиль
Группа: Админ
Сообщений: 11743
Регистрация: 12.10.2005
Где: Зеленоград

Репутация: 12
Всего: 459



Цитата(Alca @ 29.11.2009,  09:26)
Цитата

Запретить создавать объект на стеке

Как?

  Как вариант перегрузить оператор new в котором заполнить некоторое поле объекта признаком что память была выделена в куче (сигнатуру хитрую записать). В самом же конструкторе проверить сигнатуру и если не совпадает вкинуть эксепшн. Это будет рантайм запрет. Еще вариант спрятать в private конструктор и всегда создавать объект в куче при помощи функции friend-a 


--------------------
Vit вечная память.

Обсуждение действий администрации форума производятся только в этом форуме

гениальность идеи состоит в том, что ее невозможно придумать
PM ICQ Skype   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0727 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.