Alexander "SonnySlave"
😂😂😂
Vsevolod
вообще, это очень сложный вопрос
Vsevolod
чтобы созданный объект сам хранил рефренс на себя
Vsevolod
я это когда-то давно делал через всякие enable_shared_from_this и самоотстрел специальным методом
Vsevolod
я делал с shared, то есть, объект создается через метод, возвращающий std::shared_ptr<T> (с приватным конструктором) и хранит внутри себя этот shared_ptr, пока ему нужно существовать вне зависимости от внешнего мира
Vsevolod
а когда это не нужно - зовет reset, да
Vsevolod
если внешнему миру это тоже не нужно, то все подыхает
Anatoly
кто-то сохраняет weak_ptr, сам диалог примешивает вот такую фигню в виде SharedPtrReady и когда диалог умрет, weak_ptr сможет это определить:
struct SharedPtrEmptyDeletor {
template<class T>
void operator()(T* p) const {
}
};
template<typename T>
struct SharedPtrReady : public std::enable_shared_from_this<T> {
public:
SharedPtrReady() : fake_shared_ptr_(self(), SharedPtrEmptyDeletor()) {
}
protected:
T* self() {
return static_cast<T*>(this);
}
private:
std::shared_ptr<T> fake_shared_ptr_;
};
🐙 Antony
Vsevolod
почему? доступ делается через один и тот же control block всегда
🐙 Antony
Запустите под санитайзерами ваш код, в тот момент, кодга this - единственный владелец shared_ptr
Vsevolod
я не понимаю, откуда здесь может взяться UB, если класс делается через enable_shared_from_this
Vsevolod
а в delete this что плохого?
Vsevolod
тоже валидное использование, если потом не дергать этот this (в т.ч. не вызывая нестатические методы)
Anatoly
@antoshkka @berkus Вообщем ситуация там такая: создано немодальное Windows окно, единственная связь с миром C++ это void* во вспомогательной структуре класса окна. Когда окно закрывается пользователем, С++ объект, ассоциированный с этим окном, должен быть уничтожен. Этот С++ объект подписывается на событие "последнегого выдоха господина пж" и убивает себя через delete this. Такова дислокация.
Alexander "SonnySlave"
тоже валидное использование, если потом не дергать этот this (в т.ч. не вызывая нестатические методы)
Это не этот кейс? (не читал весь тред)
Before the lifetime of an object has started but after the storage which the object will occupy has been allocated or, after the lifetime of an object has ended and before the storage which the object occupied is reused or released, any pointer that refers to the storage location where the object will be or was located may be used but only in limited ways. [...] If the object will be or was of a class type with a non-trivial destructor, and the pointer is used as the operand of a delete-expression, the program has undefined behavior.
Anatoly
🐙 Antony
🐙 Antony
Anatoly
Ну, Ильюха, много людей Windows даже в глаза не видели
🐙 Antony
Ок, со стороны shared_ptr подлянки в виде бесконечной рекурсии не будет
void shared_ptr::reset() noexcept;
Effects: Equivalent to shared_ptr().swap(*this).
🐙 Antony
Дык Qt же. Там это не так убого реашается, ибо можно shared_ptr держать в коллбеке, и если владелец колбека будет уничтожен, вузовется деструктор shared_ptr и ресурс не утечёт
🐙 Antony
unordered_map<Handle, shared_ptr<MyClass> > open_windows_to_kill_without_holding_sp_in_this;
Такая конструкция поможет избежать вызова delete this?
🐙 Antony
Хай обоснован тем, что в мире с исключениями ручное управление памятью и ресурсами есть зло
Matwey
Господа, а можно ли как-то эту порнографию редуцировать, не используя препроцессор?
struct width_visitor: public boost::static_visitor<std::size_t> {
template<class T> std::size_t operator() (const image<T>& i) const {
return i.width();
}
};
struct height_visitor: public boost::static_visitor<std::size_t> {
template<class T> std::size_t operator() (const image<T>& i) const {
return i.height();
}
};
struct depth_visitor: public boost::static_visitor<std::size_t> {
template<class T> std::size_t operator() (const image<T>& i) const {
return i.depth();
}
};
Anatoly
Matwey
Дмитрий
Дмитрий
А в какой момент ты собираешься создавать объекты типа depth_visitor, например?
Matwey
Всё, как завещали нам авторы бубсов:
boost::apply_visitor(width_visitor{}, x);
Дмитрий
вот в этот момент нельзя взять адрес метода?
Matwey
ммм... нет. ведь я не знаю какой именно тип хранится в варианте
Berkus
@MasterZiv ^ вот твой кейс про окно
Berkus
выше почитай
Berkus
Александр
Anatoly
Александр
Александр
То, что Антон процитировал
Anatoly
7 постов вверх
я не понял как это применимо к "оконной" проблеме, описанной выше
Anatoly
как я писал выше через фиктивный shared_ptr?
Anatoly
покажи полный пример, нифига не пойму о чем вы говорите
Anatoly
откуда возьмется shared_ptr и кем он будет кипится?
Alexander "SonnySlave"
люди так не считают.
Alexander "SonnySlave"
не надо перевирать. Люди считают delete this невалидным в случае, который я кидал выше
Andrei
люди так не считают.
в @supapro парень именно так и думал, когда задавал вопрос.
а это уже дальше разговор перешл из разряда "неправильно в с++" до "неправильно в дизайне"
Oleg
delete this - это как goto. Лучше не использовать, но если знаешь что и зачем - то пожалуйста
🐙 Antony
Я до сих пор это подозреваю... но доказать не могу :)
Alexander "SonnySlave"
Anatoly
Схематично код, создающий немодальное окно, выглядит так:
auto wnd = std::make_unique<MyWindow>();
if( wnd->Create(... ) ) {
wnd->Show ();
wnd.reset();
}
Anatoly
@berkus @antoshkka ребята, вот пример, при закрытии окна пользователем объект MyWindow должен уйти в мир иной.
Andrei
а при delete this вызывается только деструктор или память осводобится тоже?
Egor
Egor
Anatoly
Andrei
а это когда полезно?
Andrei
как раз я думал, может ты сталкивался в работе с ситуацией, когда можно было это применить, или где-то читал.
философски понятно, а вот на практике увидеть интересно
Berkus
Berkus
идиома должна называеться goto delete this;
Berkus
Berkus
Constantine
Constantine
это гарантированно последнее сообщение
Constantine
вы обсуждаете delete this там или что?
Anatoly
да
Constantine
кажется если объект захватывает ресурс, которым не может на самом деле управлять, это даже адекватно
Constantine
хотя я все равно переживаю, когда объект суидится, имея вызов в стеке