Удаление объекта (в С++)

Модератор: Модераторы разделов

frp
Сообщения: 1445
ОС: Debian Squeeze

Удаление объекта

Сообщение frp »

Один из методов класса должен выполнять некоторые действия, а потом удалить сам объект. Как это сделать? (желательно без SIGSEGV :rolleyes: , на момент удаления гарантировано не будет ссылок на объект).
Спасибо сказали:
Аватара пользователя
Skladnoy
Сообщения: 90
ОС: Debian

Re: Удаление объекта

Сообщение Skladnoy »

А как выделена память под объект? А откуда возникла необходимость в таком необычном поведении?
Спасибо сказали:
Аватара пользователя
MUTOgen
Сообщения: 343
Статус: i like the way you move
ОС: OpenSuse 11.1

Re: Удаление объекта

Сообщение MUTOgen »

ИМХО деструкторы рулят :happy: может стоит пересмотреть алгоритм и принцип построения программы? :unsure:
Спасибо сказали:
Аватара пользователя
Aviator
Сообщения: 65
ОС: Debian GNU/Linux amd64

Re: Удаление объекта

Сообщение Aviator »

Вот так:

Код:

class SelfDeleter { public: SelfDeleter() { } ~SelfDeleter() { } void selfDeleteMethod() { delete this; } };
С уважением, Сергей.
Спасибо сказали:
Аватара пользователя
destr
Сообщения: 128
ОС: Debian

Re: Удаление объекта

Сообщение destr »

Aviator писал(а):
24.07.2008 23:35
Вот так:

А вы пробовали?:)

Код: Выделить всё

destr@des:/tmp/test$ ./a.out
*** glibc detected *** ./a.out: free(): invalid pointer: 0x00007fffa425d6d7 ***
======= Backtrace: =========
/lib/libc.so.6[0x2ab70727701d]
/lib/libc.so.6(cfree+0x76)[0x2ab707278d26]
./a.out(__gxx_personality_v0+0x151)[0x400629]
./a.out(__gxx_personality_v0+0x175)[0x40064d]
/lib/libc.so.6(__libc_start_main+0xf4)[0x2ab7072261c4]
./a.out(__gxx_personality_v0+0x41)[0x400519]
======= Memory map: ========
00400000-00401000 r-xp 00000000 08:08 507616                             /tmp/test/a.out
00600000-00601000 rw-p 00000000 08:08 507616                             /tmp/test/a.out
00601000-00622000 rw-p 00601000 00:00 0                                  [heap]
2ab706849000-2ab706864000 r-xp 00000000 08:08 483823                     /lib/ld-2.7.so
2ab706864000-2ab706867000 rw-p 2ab706864000 00:00 0
2ab706a63000-2ab706a65000 rw-p 0001a000 08:08 483823                     /lib/ld-2.7.so
2ab706a65000-2ab706b55000 r-xp 00000000 08:08 95514                      /usr/lib/libstdc++.so.6.0.10
2ab706b55000-2ab706d55000 ---p 000f0000 08:08 95514                      /usr/lib/libstdc++.so.6.0.10
2ab706d55000-2ab706d5b000 r--p 000f0000 08:08 95514                      /usr/lib/libstdc++.so.6.0.10
2ab706d5b000-2ab706d5e000 rw-p 000f6000 08:08 95514                      /usr/lib/libstdc++.so.6.0.10
2ab706d5e000-2ab706d71000 rw-p 2ab706d5e000 00:00 0
2ab706d71000-2ab706def000 r-xp 00000000 08:08 483830                     /lib/libm-2.7.so
2ab706def000-2ab706fee000 ---p 0007e000 08:08 483830                     /lib/libm-2.7.so
2ab706fee000-2ab706ff0000 rw-p 0007d000 08:08 483830                     /lib/libm-2.7.so
2ab706ff0000-2ab707006000 r-xp 00000000 08:08 483779                     /lib/libgcc_s.so.1
2ab707006000-2ab707206000 ---p 00016000 08:08 483779                     /lib/libgcc_s.so.1
2ab707206000-2ab707207000 rw-p 00016000 08:08 483779                     /lib/libgcc_s.so.1
2ab707207000-2ab707208000 rw-p 2ab707207000 00:00 0
2ab707208000-2ab707346000 r-xp 00000000 08:08 483826                     /lib/libc-2.7.so
2ab707346000-2ab707546000 ---p 0013e000 08:08 483826                     /lib/libc-2.7.so
2ab707546000-2ab707549000 r--p 0013e000 08:08 483826                     /lib/libc-2.7.so
2ab707549000-2ab70754b000 rw-p 00141000 08:08 483826                     /lib/libc-2.7.so
2ab70754b000-2ab707552000 rw-p 2ab70754b000 00:00 0
7fffa424b000-7fffa4260000 rw-p 7ffffffea000 00:00 0                      [stack]
7fffa43fe000-7fffa4400000 r-xp 7fffa43fe000 00:00 0                      [vdso]
ffffffffff600000-ffffffffff601000 r-xp 00000000 00:00 0                  [vsyscall]
Аварийный останов


main.cpp

Код: Выделить всё

destr@des:/tmp/test$ cat main.cpp
class Test
{
    public:
    Test();
    ~Test();
    public:
    void del();
};
Test::Test()
{
}

Test::~Test()
{
}
void Test::del()
{
    delete this;

}
int main (int argc, char **argv)
{
    Test t;

    t.del();
    return 0;
}

ХОтя если делать Test *t = new Test(); то вроде бы всё ок. Вобщем сомнительный метод:)
Спасибо сказали:
Аватара пользователя
Alxn1
Сообщения: 402
Статус: Красноглазик со стажем
ОС: Mavericks

Re: Удаление объекта

Сообщение Alxn1 »

destr писал(а):
24.07.2008 23:49
ХОтя если делать Test *t = new Test(); то вроде бы всё ок. Вобщем сомнительный метод:)


Не сомнительный. Просто обьекты, которые удаляют сами себя нужно исключительно по new создавать.
Спасибо сказали:
Аватара пользователя
Фантом
Сообщения: 463
ОС: openSUSE

Re: Удаление объекта

Сообщение Фантом »

destr писал(а):
24.07.2008 23:49

Код: Выделить всё

    Test t;

    t.del();

ХОтя если делать Test *t = new Test(); то вроде бы всё ок. Вобщем сомнительный метод:)


А каков смысл (и ожидаемый результат) удаления статического объекта? Либо объект создается через new, либо его не нужно (да и нельзя) удалять.
Спасибо сказали:
Аватара пользователя
Voice
Сообщения: 1073
Статус: столлманист
ОС: Debian GNU/Linux

Re: Удаление объекта

Сообщение Voice »

По моему, так идея совсем бредовая. Зачем объекту себя удалять?
Удалятся он должен из функции где он создавался.
А так получается создали объект, и после вызова мы не уверенны на что мы сейчас ссылаемся...
"И может собственных Платонов и быстрых разумом Невтонов российская земля рождать."
М. В. Ломоносов
Спасибо сказали:
Аватара пользователя
Crazy
Сообщения: 862
Статус: Адепт Дзен.
ОС: Mint, Win7.

Re: Удаление объекта

Сообщение Crazy »

Aviator писал(а):
24.07.2008 23:35
Вот так:

Код:

class SelfDeleter { public: SelfDeleter() { } ~SelfDeleter() { } void selfDeleteMethod() { delete this; } };

За такое надо руки отрывать

Desipere in loco
Спасибо сказали:
Аватара пользователя
MUTOgen
Сообщения: 343
Статус: i like the way you move
ОС: OpenSuse 11.1

Re: Удаление объекта

Сообщение MUTOgen »

Aviator писал(а):
24.07.2008 23:35
Вот так:

Код:

class SelfDeleter { public: SelfDeleter() { } ~SelfDeleter() { } void selfDeleteMethod() { delete this; } };

По-моему это очень опасная ситуация, сулит нам при некоторых условиях Сигментэйшен фаултом :)
Спасибо сказали:
Аватара пользователя
/dev/random
Администратор
Сообщения: 5456
ОС: Gentoo

Re: Удаление объекта

Сообщение /dev/random »

destr,
Объекты, созданные статически, удаляются автоматически, когда исполнение переходит за пределы области видимости данного объекта. Других способов удаления статических объектов языком не предусмотрено. Вручную можно (и нужно) удалять только объекты, созданные оператором new.

Так что топикстартер мог говорить только о динамически созданном объекте.
Спасибо сказали:
Аватара пользователя
Aviator
Сообщения: 65
ОС: Debian GNU/Linux amd64

Re: Удаление объекта

Сообщение Aviator »

MUTOgen писал(а):
25.07.2008 20:26
По-моему это очень опасная ситуация, сулит нам при некоторых условиях Сигментэйшен фаултом :)

Человек спросил как динамический объект может удалить сам себя. Я ответил. :)
А указанный мною метод используется только вместе с механизмом подсчета ссылок, чтобы не было SegFault.
Такой подход освещается в книге Александреску и библиотеке Loki, и используется в COM-подобных компонентных системах.

Crazy писал(а):
25.07.2008 20:04
За такое надо руки отрывать

Ну тогда руки оторвите разработчикам COM, NSCOM, и прочих COM-подобных библиотек,
а также и Александреску за компанию. :D

Ладно, ладно. Что я тут флейм развожу... C++ вообще допускает массу потенциально опасных вещей. Надо осторожно...
С уважением, Сергей.
Спасибо сказали:
frp
Сообщения: 1445
ОС: Debian Squeeze

Re: Удаление объекта

Сообщение frp »

Метод то что надо. Объект создается динамически, иначе я бы не создавал тему. А насчет Segmentation Fault в коде у меня указателей на объект в момент удаления уже нет (об этом заботится мой метод до удаления).
Спасибо сказали:
Аватара пользователя
MUTOgen
Сообщения: 343
Статус: i like the way you move
ОС: OpenSuse 11.1

Re: Удаление объекта

Сообщение MUTOgen »

frp писал(а):
25.07.2008 22:30
Метод то что надо. Объект создается динамически, иначе я бы не создавал тему. А насчет Segmentation Fault в коде у меня указателей на объект в момент удаления уже нет (об этом заботится мой метод до удаления).

ну тогда вам и карты в руки :drinks:
Спасибо сказали:
Аватара пользователя
Crazy
Сообщения: 862
Статус: Адепт Дзен.
ОС: Mint, Win7.

Re: Удаление объекта

Сообщение Crazy »

А такие методы не подходят:
Явный вызов деструктора;
Использования дополнительного класса, для уборки мусора;
Использование new delit(тут вызов деструктора производится автоматически).
Ну тогда руки оторвите разработчикам COM, NSCOM, и прочих COM-подобных библиотек,
а также и Александреску за компанию.

Вот и оторвал бы. Т.к. такой метод можно отнести к недочётам проектирования.

Desipere in loco
Спасибо сказали:
Аватара пользователя
Aviator
Сообщения: 65
ОС: Debian GNU/Linux amd64

Re: Удаление объекта

Сообщение Aviator »

Crazy писал(а):
26.07.2008 11:38
А такие методы не подходят:
Явный вызов деструктора;
Использования дополнительного класса, для уборки мусора;
Использование new delit(тут вызов деструктора производится автоматически).

А если вы используете динамическое связывание? А вдобавок к этому и приложение у вас многопоточное и работает на нескольких машинах, для распараллеливания вычислений?
С уважением, Сергей.
Спасибо сказали:
Аватара пользователя
Crazy
Сообщения: 862
Статус: Адепт Дзен.
ОС: Mint, Win7.

Re: Удаление объекта

Сообщение Crazy »

Aviator писал(а):
26.07.2008 12:45
Crazy писал(а):
26.07.2008 11:38
А такие методы не подходят:
Явный вызов деструктора;
Использования дополнительного класса, для уборки мусора;
Использование new delit(тут вызов деструктора производится автоматически).

А если вы используете динамическое связывание? А вдобавок к этому и приложение у вас многопоточное и работает на нескольких машинах, для распараллеливания вычислений?

Одно другому не мешает.
А указанный мною метод используется только вместе с механизмом подсчета ссылок

В этом случае объект удаляется, когда удаляется последняя ссылка на него. Там работает деструктор и delete.

Desipere in loco
Спасибо сказали:
Аватара пользователя
Electronix
Сообщения: 53
ОС: Slackware, Suse, XP

Re: Удаление объекта

Сообщение Electronix »

frp писал(а):
24.07.2008 21:56
Один из методов класса должен выполнять некоторые действия, а потом удалить сам объект. Как это сделать? (желательно без SIGSEGV , на момент удаления гарантировано не будет ссылок на объект).

Мало информации. Во-первых, чтобы правильно удалить обьект нужно знать каким образом для него выделена память.
Обычно для этого используют умные указатели. std::auto_ptr, boost::shared_ptr или свою реализацию.
We have no beginning, we have no end. We are infinite.
Спасибо сказали: