- 01
- 02
- 03
- 04
- 05
- 06
- 07
- 08
- 09
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
void Exf2dMW::closeEvent(QCloseEvent* event)
{
int win_num = _winManager->numberOfModellingWindows();
// if more than one modelling windows, just destroy current one:
if (win_num > 1) {
event->accept();
delete this;
}
// if only one window and handle closing model properly, then destroy it:
else {
if( handleCloseModel() ) {
event->accept();
delete this;
delete _winManager;
}
else
event->ignore();
}
}
Еще кусочек говнокода коллеги, я не думал что так можно писать..
absolut 08.03.2011 15:42 # +2
ReL 08.03.2011 16:10 # −2
unsigned char buf[] = { 0x01, 0x02, 0x03, 0x04 };
delete buf; printf("0x%08X - 0x%08X\n", buf, *((unsigned int*)buf));
delete this бывало встречал в коммерческих проектах... по большому счету криминальное здесь только delete локальной переменной... хотя в принципе тоже должно работать, если this был не последним выделенным аллоком на странице, и если между delete this и delete локальной переменной не встрянет другой поток, который перетрет ее значение...
kitaec 08.03.2011 16:13 # 0
gegMOPO4 08.03.2011 21:11 # 0
gegMOPO4 08.03.2011 21:19 # 0
Можно предположить, что есть менеджер окон, есть несколько окон, на каждое навешен обработчик события закрытия, размещённый в динамической памяти. Если окон несколько -- event->accept() закрывает сответствующее окно, обработчик больше ни с чем не связан и не нужен, удаляется. Если осталось последнее окно, handleCloseModel() запрашивает у пользователя подтверждение и либо закрывает это окно и удаляет уже не нужный менеджер, либо игнорирует событие. Всё нормально.
kitaec 08.03.2011 21:30 # 0
gegMOPO4 08.03.2011 22:03 # 0
ctm 08.03.2011 22:05 # 0
но структуру системы проще понять и поддерживать, если сущности создаются и удаляются там, где они используются, а не так что создадим здесь, тут что-то там вызовем (явно не деструктор) и, опа, оно уже удалено:(
Lure Of Chaos 08.03.2011 22:27 # +3
о майне факен готт.......
nil 12.03.2011 15:33 # +2
sneak-peek 08.03.2011 23:04 # −2
class A { TypeA fieldA; ... };
class B { public: TypeB fieldB; void DeleteB() { delete this; } ... };
class C : A, public B { ... };
...
C *c = new C();
C->DeleteB();
всё равно что сделать так:
void Fn_DeleteB(B *b) { delete b; }
Fn_DeleteB(new C());
метод DeleteB() получит в качестве this не указатель на (*c), а указатель на с->fieldB, т.е. не на начало области освобождаемой памяти.
Даже если наследоваться никто не будет, не думаю что так стоит писать (
Lure Of Chaos 08.03.2011 23:42 # +3
не думаю, что корректно удалять себя, т.к. получится, что мы находимся внутри несуществующего объекта
absolut 09.03.2011 00:04 # 0
Lure Of Chaos 09.03.2011 00:07 # 0
absolut 09.03.2011 00:11 # 0
Lure Of Chaos 09.03.2011 00:13 # +3
sneak-peek 09.03.2011 00:24 # 0
nil 12.03.2011 15:36 # +1
А вообще, интересная проблема о нахождении внутри несуществующего объекта — на самом стыке программирования и философии!
TheCalligrapher 09.03.2011 02:36 # +5
В языке С++ выполнять полиморфное удаление объекта (т.е удаление через указатель на базовый подобъект) разрешается только в том случае, если этот базовый подобъект имеет виртуальный деструктор. Вы в своем коде нарушили это правило, поэтому Ваш код порождает неопределенное поведение (а уж какой там указатель прийдет в `delete` - на `fieldB` или еще куда - это бесполезное гадание на кофейной гуще).
Ваш код ничем принципиально не оличается от обычного
и, еще раз, ни к `delete this`, ни к множественному наследованию никакого прямого отношения не имеет.
Добавьте в класс `B` виртуальный деструктор, чтобы соблюсти требования языка С++, и сразу все станет работать нормально, даже с множественным наследованием :)
gegMOPO4 09.03.2011 10:22 # 0
absolut 09.03.2011 11:11 # 0
gegMOPO4 09.03.2011 11:32 # 0
Dummy00001 09.03.2011 00:26 # −2
с другой стороны, я лицезрел подобную фишку в одной системе - удаление объекта получателя сообщения внутри обработчика этого же сообщения. не так откровенно, но тем неменее. и я видел как это весьма спектакулярно и произвольно валило приложение весьма разнообразными способами: фреймворк пытался что-то там еще с этим объектом делать в эпилоге кода диспатча сообщений. имеет смысл на мэйл листах вашего фреймворка поспрашивать.
TheCalligrapher 09.03.2011 02:45 # +3
Аргументы типа "объект может быть на стеке" - бред сивой кобылы. Если я, автор объекта, сказал, что объект не может быть "на стеке", значит от там быть не может. А если кто-то умудрится его там создать - вот тот пусть потом и расхлебывает возникшие проблемы. (Добро пожаловать в С++!)
Разумеется, если объекты предназначены исключительно для динамческого создания, то не составит труда исключить их статическое создание или локальное создание. Способов достичь этого много. (Static constructor idiom - лишь один пример).
Постить вырванный из контекста код с `delete this` и утверждать что из-за этого он является говнокодом - дилетантство самого низкого пошиба.
Потенциал для говнокодовости в этом примере, конечно, есть. В частности, имете место обращение к некоему `_winManager` после `delete this`. Если `_winManager` - поле уже удаленного объекта , то мы действительно имеем дело с говнокодом. Но из примера не видно, откуда берется этот `_winManager`, поэтому судить невозможно.
kitaec 09.03.2011 13:09 # +1
Я бы не сказал что устоявшаяся и широко распространенная. Как тут уже подметили, создание и удаление объекта должно быть подконтрольно одной сущности, а так как очевидно, что объект не может создать себя сам, неправы тут Вы. И не надо кидаться выражениями, типа "дилетанство самого низкого пошиба" или "бред сивой кобылы".
gegMOPO4 09.03.2011 15:12 # +1
Это действительно устоявшаяся широко распространенная идиома. Но применимая в редких конкретных ситуациях, в комплексе с другими средствами.
kitaec 09.03.2011 15:17 # 0
gegMOPO4 09.03.2011 15:49 # +1
Например, объект с внутренним счётчиком ссылок. Метод grab увеличивает счётчик на 1, метод ungrab — уменьшает, и, если он достиг 0, удаляет объект. Это эффективнее smart_ptr.
Или же create при некоторых условиях берёт уже созданный объект из готового статического пула, а destroy, если объект был из пула, возвращает его туда, не разрушая.
kitaec 09.03.2011 17:50 # 0
P.S. в любом случае к подопытному коду это не относится :)
sneak-peek 09.03.2011 03:14 # +1
guest 10.03.2011 03:13 # 0
>Большинству современных языков программирования не хватет морально-этической и чувственной составляющей...
istem 10.03.2011 09:16 # −1
"Здравствуйте, меня зовут Николай Валуев. Немного о себе. Сейчас я профессиональный боксёр. Также у меня есть рот. И ещё я туда ем."
Может пригласить автора на ГК?