Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Самоудаление объекта (delete this)


Автор: BabySG 4.10.2005, 22:00
Собственно: имеется примерно такое

Код

class Base{
    virtual void a() { /* что-то там */ };
}

class Derived : public Base{
    virtual void a(){
       // Что-то там
       ABC::Destroy() ;                             // На самом деле, здесь стоит указатель на destroy() из класса АBC
       // ТОЧКА А
       Base::a();
   }
}

class ABC{
   void Destroy(){
       // ТОЧКА Б
   };
}



Так вот, стоит вопрос:
при выполнении определенных условий, объект класса Derived может захотеть удалиться.
Где это лучше сделать? В точке А или точке Б?

PS. В Derived::a() ОБЯЗАТЕЛЬНО в конце должна вызваться функция базового...



Автор: __Sergey__ 4.10.2005, 23:26
Цитата(BabySG @ 4.10.2005, 22:00)
объект ... может захотеть

я балдею!
когда это было, чтобы объект действовал "по своему усмотрению", а не так как его
запрограммировали.
или я чего-то не понял, или формулируй вопрос правильно smile
а вообще-то весьма жутковатая схема построения классов ;)

Автор: np9mi7 5.10.2005, 00:12
Попытка удаление самого себя - ошибка проектирования;

Лучше напиши некое подобие владельца объекта, который бы смотрел на то чем владеет и принимал решение об удалении;

Вообще не понятен кусок кода:
Код

ABC::Destroy();
, ABC не базовый для Derived, да и функция не статическая. Что ты имел ввиду?

Автор: Mayk 5.10.2005, 06:53
Чур меня чур. Точка А в данном контексте эквивалентна точке Б.
А вообще ничего, что после освобождения состояние памяти будет неопределено и вызов Base::a() может закончится крахом?

Автор: BabySG 5.10.2005, 07:56
Цитата(Mayk @ 5.10.2005, 06:53)
Чур меня чур. Точка А в данном контексте эквивалентна точке Б.
А вообще ничего, что после освобождения состояние памяти будет неопределено и вызов Base::a() может закончится крахом?

http://forum.vingrad.ru/index.php?showtopic=53760&hl=delete+this
Добавлено @ 07:57
Цитата(__Sergey__ @ 4.10.2005, 23:26)
Цитата(BabySG @ 4.10.2005, 22:00)
объект ... может захотеть

я балдею!
когда это было, чтобы объект действовал "по своему усмотрению", а не так как его
запрограммировали.
или я чего-то не понял, или формулируй вопрос правильно smile
а вообще-то весьма жутковатая схема построения классов ;)

К примеру - есть окно, при нажатии на кнопку закрытия окна окно должно закрыться.

Автор: np9mi7 5.10.2005, 07:59
Цитата
К примеру - есть окно, при нажатии на кнопку закрытия окна окно должно закрыться.
, так и закрывай его а не убивай......

Автор: BabySG 5.10.2005, 07:59
Цитата(np9mi7 @ 5.10.2005, 00:12)
Попытка удаление самого себя - ошибка проектирования;

Лучше напиши некое подобие владельца объекта, который бы смотрел на то чем владеет и принимал решение об удалении;

Вообще не понятен кусок кода:
Код

ABC::Destroy();
, ABC не базовый для Derived, да и функция не статическая. Что ты имел ввиду?

См. мой ответ по поводу владельца выше.
А насчет ABC::destroy()
Выглядит на самом деле так:

Код


(((Base*) objPtr)->*methodPtr)();



Рассматривался вопрос недалеко тут в форуме...
Добавлено @ 08:01
Цитата(np9mi7 @ 5.10.2005, 07:59)
Цитата
К примеру - есть окно, при нажатии на кнопку закрытия окна окно должно закрыться.
, так и закрывай его а не убивай......

В данном случае равнозначно удалению.

Нужно освободить память - так как таких окон много.

Автор: Mayk 5.10.2005, 08:22
Цитата(BabySG @ 5.10.2005, 11:56)

http://forum.vingrad.ru/index.php?showtopi...&hl=delete+this

http://google.com. мы будем обсуждать вопрос или раскидываться ссылками без объяснений что к чему?
Смотрим по данной ссылке:
Цитата(chipset @ 30.5.2005, 08:14)
class foo
{
    public:
    int a;
int    delete_it()
{
    a = 7;
    cout<<"Before "<<a<<endl;
    delete this;
    a = 2;
    cout<<"After "<<a<<endl;
    return 2;
}
};
- скомпилировалось и запустилось и созданное на стёке и в куче.
Только вот результат был:
Цитата
Before 7
After 0


Base::a() обратится к какой-нить ф-ции из виртальной таблицы и "здравствуй дебагер"
Цитата(BabySG @ 5.10.2005, 11:59)
Нужно освободить память - так как таких окон много.

Ну так освобождай в конце ф-ции. После вызовы base::a,
или вне ф-ции.

Автор: BabySG 5.10.2005, 15:13
Цитата(Mayk @ 5.10.2005, 08:22)

Цитата(BabySG @ 5.10.2005, )

http://forum.vingrad.ru/index.php?showtopi...&hl=delete+this

http://google.com. мы будем обсуждать вопрос или раскидываться ссылками без объяснений что к чему?
Смотрим по данной ссылке:

[...SKIP...]

Base::a() обратится к какой-нить ф-ции из виртальной таблицы и "здравствуй дебагер"


Никаких обид - текст порезался после ссылки.
Привёл её к тому, что в варианте с членами-данными может еще прокатит.
Вот и интересно стало - что насчет функций.


Цитата(Mayk @ 5.10.2005, 08:22)

Цитата(BabySG @ 5.10.2005, )
Нужно освободить память - так как таких окон много.

Ну так освобождай в конце ф-ции. После вызовы base::a,
или вне ф-ции.

так в том-то и вопрос, что base::a должно быть последней строкой.
Т.е. нужен вариант, а-ля:
Код

   delete this;
   Base::a;


, а вот так не катит:
Код

   Base::a;
   delete this;


Автор: Mayk 5.10.2005, 16:16
Цитата(BabySG @ 5.10.2005, 19:13)
delete this;
  Base::a;

Дык это тоже не катат, если нет гарантии, что base::a не обращается к данным/vtable.
Прога (если повезет) просто вылетит(ибо состояние памяти не определено).
Код

struct A
{       int a;
        A(){a=657;}
        void f(){delete this; cout << a << endl;    }
};
int main(int argc, char** argv)
{
        A* a = new A;
        a->f();
}

вот это выдает 0, а не 657.

Что делает Base::A? Почему он должен вызываться после delete? Ведь после delete объекта уже нет.
А такой вариант не пойдёт smile
Код

    virtual void a(){
       ABC::Destroy() ;
       Derived::~Derived();
       Base::a();
       delete this;
   }

Выглядит надо сказать уродски.





Автор: BabySG 5.10.2005, 21:42
smile Практически так же для проверки накатал smile

Решил я проблемку. В итоге получилось (на пальцах) примерно так:

В ABC::Destroy() объект, который хочет удалиться, ставиться на пометку в очередь таких же.
По окончанию обработки "окон", просматривается сия очередь и удаляется в тартары все из нее.
В итоге: объект будет правильно удален и можно вызвать ф-ию базового класса.

PS. А выглядит действительно по уродски, поэтому и не писал так раз, а два - единый стиль надо соблюсти - вызов базового обработчика всегда в конце.

PPS. Спасибо за участие!

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)