Re[3]: RAII vs RAII
От: ViTech  
Дата: 21.09.18 08:02
Оценка: 2 (2) +6 :)
Здравствуйте, rg45, Вы писали:

R>И сразу хочу отметить, что я вижу как раз то, о чем говорил здесь: http://rsdn.org/forum/cpp/7249960.1
Автор: rg45
Дата: 18.09.18
. А именно, не очень удачный дизайн. Судите сами: мы имеем проблему невозможности получения в конструкторе владеющего указателя на конструируемый класс. Вопрос: почему нам нужен этот указатель? А потому, что мы так запроектировали. А что нам мешает изменить этот дизайн? Да ничего!


Ну как что мешает... Если перепроектировать, то становится не интересно. А как же полёт фантазии, муки творчества? Передать недостроенный this в конструктор базового класса, приватно наследовать интерфейс, возможно стать владельцем себя самого. Искать RAII в C++. Грустить, что его там нет. Выбрасывается целый пласт деятельности и переживаний. Скучно живёте, товарищи .

Если всё перепроектировать, то можно дойти до чего угодно. Например, задаться вопросами: Tree уникально владеет своими children или нет? Т.е. может ли один child находиться одновременно в двух разных Tree (или ещё у кого-нибудь во владении вообще)? Точно ли тут нужен std::shared_ptr для children? И как следствие std::enable_shared_from_this для Tree. Всё же скатится в банальность .
Пока сам не сделаешь...
Re: RAII vs RAII
От: swingus  
Дата: 19.09.18 00:12
Оценка: +5
Во первых, непонятно, почему именно shared_ptr выбран для RAII, а не объект на стеке или unique_ptr. Во вторых, как использование RAII приводит к вызову shared_from_this() в конструкторе. Это ортогональные вещи.

Здравствуйте, dipso, Вы писали:

D>Нас столько лет учили RAII, а потом бьют по рукам.
Re: RAII vs RAII
От: rg45 СССР  
Дата: 18.09.18 20:52
Оценка: +3
Здравствуйте, dipso, Вы писали:

D>стандартных умных указателей первое на что натыкаешься — как получить std::shared_ptr из this.

D>И оп-па первые грабли.Вроде бы это можно решить использованием std::enable_shared_from_this.
D>Но std::enable_shared_from_this::shared_from_this нельзя использовать в конструкТОРАХ.

И очень хорошо, что нельзя. Ибо в конструкторе не известна ни область памяти, ни способ, которым объект создается, ни то, какми способом он должен удаляться. Если возникает потребность в получении shared_ptr на объект внутри его конструктора, то, ИМХО, это повод для пересмотра дизайна.
--
Re[2]: RAII vs RAII
От: rg45 СССР  
Дата: 19.09.18 06:52
Оценка: +3
Здравствуйте, Alexander G, Вы писали:

D>>А классический RAII возможен(наверное, ещё не пробовал) только с каким нибудь

D>>boost::intrusive_ptr(abandoned), in_proposal::retain_ptr.

AG>Эти справляются с расшариванием в конструкторе. Но не в деструкторе. и weak_ версии у них нет.


Зачем вообще может понадобиться владеющий указатель в конструторе? Что можно делать с владеющим указателем на объект, время жизни которого еще не началось? Ну, допустим, получили мы его, что дальше?
--
Re[6]: RAII vs RAII
От: ViTech  
Дата: 19.09.18 15:43
Оценка: +2
Здравствуйте, uzhas, Вы писали:

U>накидал такой пример: https://ideone.com/8cDrRG


По-моему, слишком спорный пример, чтобы на его основе что либо показывать. Ну допустим есть такой код. В теме идёт речь о RAII, соответственно о владении объектами и ответственными за их уничтожение. В вашем примере Car владеет logger(должен его уничтожать когда сам удаляется) или нет? Если владеет, то желательно ещё указать тип владения (уникальное/совместное/...?). Для наглядности перепишите этот пример с new и delete. Если Car всё же владеет logger, то какое поведение ожидается, когда владение объектом передаётся самому себе? Какое отношение к этому имеет RAII именно в C++? Можно ли делать подобные вещи в других языках, например со сборкой мусора, в Jave какой-нибудь ?
Пока сам не сделаешь...
Re[3]: RAII vs RAII
От: B0FEE664  
Дата: 05.10.18 08:22
Оценка: +2
Здравствуйте, dipso, Вы писали:

D> Вопрос — можно ли средствами языка заставить людей не создавать объекты на стеке.

Да.
И каждый день — без права на ошибку...
Re[5]: RAII vs RAII
От: uzhas Ниоткуда  
Дата: 19.09.18 13:20
Оценка: 6 (1)
Здравствуйте, rg45, Вы писали:

R>Есть какой-нибудь относительно несложный пример, показывающий необходимость и оправдывающий такие подходы?


накидал такой пример: https://ideone.com/8cDrRG
Re[6]: RAII vs RAII
От: σ  
Дата: 19.09.18 13:45
Оценка: +1
Здравствуйте, uzhas, Вы писали:

U>Здравствуйте, rg45, Вы писали:


R>>Есть какой-нибудь относительно несложный пример, показывающий необходимость и оправдывающий такие подходы?


U>накидал такой пример: https://ideone.com/8cDrRG


Притянуто за уши приватное наследование.
Re[8]: RAII vs RAII
От: σ  
Дата: 19.09.18 13:46
Оценка: +1
Здравствуйте, uzhas, Вы писали:

U>Здравствуйте, rg45, Вы писали:


R>>Ну хорошо, для "сырых" указателей хоть какой-то use case есть.


U>в данном примере можешь заменить сырой указатель на умный, суть не изменится.

U>либо класс Car надеется, что ILogger кто-то снаружи держит

А с Dependency Injection разве так не должно быть всегда?
Re[9]: RAII vs RAII
От: uzhas Ниоткуда  
Дата: 19.09.18 13:55
Оценка: +1
Здравствуйте, rg45, Вы писали:

R>здесь можно обойтись


можно на сях писать без плюсов. мне кажется, спор ни о чём, я сдаюсь
RAII vs RAII
От: dipso  
Дата: 18.09.18 19:14
Оценка:
Нас столько лет учили RAII, а потом бьют по рукам.
Любителям std::shared_ptr посвещается. Вроде бы и да, автоматическое удаление итд,хотя
трудно забыть delete если сделал new, просто согласен
есть не очевидные не решаемые просто моменты которые
обсуждались и здесь , и на хабре, и на sof.

Ну вот допустим хочу я сделать всё в классическом RAII.
Для меня главное всё должно быть в зазубренной последовательности.
Базовый класс, члены, текущий конструктор и наоборот при удалении.
Но если вы вдруг поддаётесь общей тенденции об использовании
стандартных умных указателей первое на что натыкаешься — как получить std::shared_ptr из this.
И оп-па первые грабли.Вроде бы это можно решить использованием std::enable_shared_from_this.
Но std::enable_shared_from_this::shared_from_this нельзя использовать в конструкТОРАХ.
А это ломает вообще всё, даже то что раньше делалось простым наследованием или заменой
наследования включением.
Казалось бы ну есть make-функции. Но во первых их два типа:
std::make_shared без делетера,
статические(темплейт наверное) в базовом классе(мейби).

Но мне надо ограничить методы создания объектов.
Либо можно всё — и на стеке и в куче.
Либо только куча.

Короче я не всё написал, но может кто понял о чём я.
Короче вариант с виртуальным конструктором исключает make_shared(удалённые частичные специализации).
А классический RAII возможен(наверное, ещё не пробовал) только с каким нибудь
boost::intrusive_ptr(abandoned), in_proposal::retain_ptr.

В общем хочу чтобы shared_ptr и классический RAII(в обычных конструкторах) жили вместе как нибудь.
А да забыл про переопределение new.
Ладно у кого какие варианты7
Re[2]: RAII vs RAII
От: dipso  
Дата: 18.09.18 21:01
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, dipso, Вы писали:


D>>стандартных умных указателей первое на что натыкаешься — как получить std::shared_ptr из this.

D>>И оп-па первые грабли.Вроде бы это можно решить использованием std::enable_shared_from_this.
D>>Но std::enable_shared_from_this::shared_from_this нельзя использовать в конструкТОРАХ.

R>И очень хорошо, что нельзя. Ибо в конструкторе не известна ни область памяти, ни способ, которым объект создается, ни то, какми способом он должен удаляться. Если возникает потребность в получении shared_ptr на объект внутри его конструктора, то, ИМХО, это повод для пересмотра дизайна.


Ну и ... Свои make-функции поверх make-shared? Мне нужна двухфакторная инициализация?
Re: RAII vs RAII
От: Alexander G Украина  
Дата: 19.09.18 03:39
Оценка:
Здравствуйте, dipso, Вы писали:

D>Короче я не всё написал, но может кто понял о чём я.

D>Короче вариант с виртуальным конструктором исключает make_shared(удалённые частичные специализации).
D>А классический RAII возможен(наверное, ещё не пробовал) только с каким нибудь
D>boost::intrusive_ptr(abandoned), in_proposal::retain_ptr.

Эти справляются с расшариванием в конструкторе. Но не в деструкторе. и weak_ версии у них нет.

D>В общем хочу чтобы shared_ptr и классический RAII(в обычных конструкторах) жили вместе как нибудь.

D>А да забыл про переопределение new.
D>Ладно у кого какие варианты7

Ну-у, есть вариант, что "классический RAII" — это вообще без счётчиков ссылок, когда известно кто кем владеет.
shared_ptr и intrusive_ptr только когда очень надо. shared_from_this — когда очень-очень.
Чем больше всё под контролем, тем меньше эти проблемы shared_ptr мешают.

Ещё есть языки со сборкой мусора, в плане освобождения памяти сборка мусора считается убийцей RAII.
(Но при этом полностью отключить мозг не позволяет даже сборка мусора )
Русский военный корабль идёт ко дну!
Re[3]: RAII vs RAII
От: rg45 СССР  
Дата: 19.09.18 06:37
Оценка:
Здравствуйте, dipso, Вы писали:

R>>И очень хорошо, что нельзя. Ибо в конструкторе не известна ни область памяти, ни способ, которым объект создается, ни то, какми способом он должен удаляться. Если возникает потребность в получении shared_ptr на объект внутри его конструктора, то, ИМХО, это повод для пересмотра дизайна.


D>Ну и ... Свои make-функции поверх make-shared? Мне нужна двухфакторная инициализация?


Зачем? После того, как объект сконструирован и передан во владение, можно будет спокойно пользовастья механизмом enable_shared_from_this — хоть внутри объекта, хоть снаружи, без всяких костылей и двухфазных инициализаций.
--
Re[3]: RAII vs RAII
От: uzhas Ниоткуда  
Дата: 19.09.18 11:35
Оценка:
Здравствуйте, rg45, Вы писали:

R>Зачем вообще может понадобиться владеющий указатель в конструторе? Что можно делать с владеющим указателем на объект, время жизни которого еще не началось? Ну, допустим, получили мы его, что дальше?


сырой указатель довольно часто используют в конструкторе (передают в базовые классы, например). несырой (более умный) указатель могут использовать по той же причине
да, это немного опасно (даже компилятор иногда ворнинг выдает), надо быть внимательным в обоих случаях, но при некоторой осторожности это работает, как и планируется
Re[4]: RAII vs RAII
От: rg45 СССР  
Дата: 19.09.18 12:01
Оценка:
Здравствуйте, uzhas, Вы писали:

U>Здравствуйте, rg45, Вы писали:


R>>Зачем вообще может понадобиться владеющий указатель в конструторе? Что можно делать с владеющим указателем на объект, время жизни которого еще не началось? Ну, допустим, получили мы его, что дальше?


U>сырой указатель довольно часто используют в конструкторе (передают в базовые классы, например). несырой (более умный) указатель могут использовать по той же причине


Сырой указатель на что, на конструируемый объект? И зачем может понадобиться передавать его в базовый класс, когда его можно там без труда вычислить? Разве что, при виртуальном наследовании? Тем более не понятно, зачем может понадобиться передавать в базовый класс владеющий указатель на конструируемый объект.

U>да, это немного опасно (даже компилятор иногда ворнинг выдает), надо быть внимательным в обоих случаях, но при некоторой осторожности это работает, как и планируется


Все это программирование на грани фола. При передаче указателя на конструируемый объект в базовый класс, объект, адресуемый указателем не только еще не начал свое время жизни, он даже еще не начал конструироваться (поскольку объект базового класса конструируется первым). Для того, чтобы прибегать к таким мерам, должны существовать какие-то веские причины. Есть какой-нибудь относительно несложный пример, показывающий необходимость и оправдывающий такие подходы? Ну и на всякий случай, ошибки проектирования мне не хотелось бы рассматривать как веские причины
--
Отредактировано 19.09.2018 12:03 rg45 . Предыдущая версия .
Re[6]: RAII vs RAII
От: rg45 СССР  
Дата: 19.09.18 13:30
Оценка:
Здравствуйте, uzhas, Вы писали:

R>>Есть какой-нибудь относительно несложный пример, показывающий необходимость и оправдывающий такие подходы?


U>накидал такой пример: https://ideone.com/8cDrRG


Ну хорошо, для "сырых" указателей хоть какой-то use case есть. (Хотя, в таких случаях я предпочитаю отдавать ссылку, а не указатель, но не суть). Здесь можно было бы начать задавать вопросы типа "почему наследование, а не агрегация" и т.д. Но не будем, будем считать, что есть обоснование. Но изначально ведь речь шла о необходимости получения в конструкторе именно владеющего указателя на конструируемый объект. Вот теперь бы это еще как-то обосновать.
--
Отредактировано 19.09.2018 13:36 rg45 . Предыдущая версия . Еще …
Отредактировано 19.09.2018 13:33 rg45 . Предыдущая версия .
Re[7]: RAII vs RAII
От: uzhas Ниоткуда  
Дата: 19.09.18 13:37
Оценка:
Здравствуйте, rg45, Вы писали:

R>Ну хорошо, для "сырых" указателей хоть какой-то use case есть.


в данном примере можешь заменить сырой указатель на умный, суть не изменится.
либо класс Car надеется, что ILogger кто-то снаружи держит (хрупко, что с ссылками, что с сырыми указателями), либо сам его держит через умный указатель (уже надежнее, но накладнее)
Re[5]: RAII vs RAII
От: σ  
Дата: 19.09.18 13:47
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, uzhas, Вы писали:


U>>Здравствуйте, rg45, Вы писали:


R>>>Зачем вообще может понадобиться владеющий указатель в конструторе? Что можно делать с владеющим указателем на объект, время жизни которого еще не началось? Ну, допустим, получили мы его, что дальше?


U>>сырой указатель довольно часто используют в конструкторе (передают в базовые классы, например). несырой (более умный) указатель могут использовать по той же причине


R>Сырой указатель на что, на конструируемый объект? И зачем может понадобиться передавать его в базовый класс, когда его можно там без труда вычислить?


:| Как?
Re[8]: RAII vs RAII
От: rg45 СССР  
Дата: 19.09.18 13:47
Оценка:
Здравствуйте, uzhas, Вы писали:

R>>Ну хорошо, для "сырых" указателей хоть какой-то use case есть.


U>в данном примере можешь заменить сырой указатель на умный, суть не изменится.

U>либо класс Car надеется, что ILogger кто-то снаружи держит (хрупко, что с ссылками, что с сырыми указателями), либо сам его держит через умный указатель (уже надежнее, но накладнее)

Во-первых, речь шла не просто об умных указателях, а о владеющих. А во-вторых, я интересовался примером, который бы показывал НЕОБХОДИМОСТЬ получения в конструкторе владеющего указателя на конструируемый объект. Твой пример такой необходимости не показывает, поскольку здесь можно обойтись без всяких умных указателей. Ну а нет необходимости, нет и проблемы, не так ли?
--
Re[6]: RAII vs RAII
От: rg45 СССР  
Дата: 19.09.18 15:20
Оценка:
Здравствуйте, σ, Вы писали:

R>>Сырой указатель на что, на конструируемый объект? И зачем может понадобиться передавать его в базовый класс, когда его можно там без труда вычислить?


σ>:| Как?


Согласен, в общем случае нельзя. Но это и не основной вопрос обсуждения, в то же время.
--
Re: RAII vs RAII
От: dipso  
Дата: 20.09.18 10:24
Оценка:
Прошу прощения, не все ответы прочитал, нет столько времени, но...
Самый простой вариант — реализовать класс Tree пытаясь использовать
нынешнию RAII идеологию. Пишу прямо в тегах, сильно не пинайте.

template<typename T>
class Tree
{
public:

  using ptr_type = std::shared_ptr<T>;
  using weakptr_type = std::weak_ptr<T>;

Tree(ptr_type parent)
{
  SetParent(parent);
}

ptr_type Parent()
{
  return m_parent.lock();
} 

void SetParent(ptr_type parent) 
{
  m_parent = parent;

}

private:

weakptr_type m_parent;
std::vector<ptr_type> m_children;
};


Нужно наследование от std::enable_shared_from_this.
Конструктор по умолчанию не важен.Хочу наследовать от
Tree. Включение против наследования не поможет.
Интересуют конструкторы.
В любом случае std::bad_weak_ptr.
Re[2]: RAII vs RAII
От: ViTech  
Дата: 20.09.18 11:59
Оценка:
Здравствуйте, dipso, Вы писали:

D>Прошу прощения, не все ответы прочитал, нет столько времени, но...

D>Самый простой вариант — реализовать класс Tree пытаясь использовать
D>нынешнию RAII идеологию. Пишу прямо в тегах, сильно не пинайте.

Если m_parent типа weakptr_type(и это правильно), то зачем в Parent()/SetParent() используется ptr_type? Попробуйте изменить на weakptr_type.

D>Нужно наследование от std::enable_shared_from_this.

D>Конструктор по умолчанию не важен.Хочу наследовать от
D>Tree. Включение против наследования не поможет.
D>Интересуют конструкторы.
D>В любом случае std::bad_weak_ptr.

Я бы не стал наследоваться от такого Tree. Но если так надо... Пишите код, с которым возникают проблемы, чтобы было от чего отталкиваться. На предположениях далеко не уедешь .
Пока сам не сделаешь...
Re[3]: RAII vs RAII
От: dipso  
Дата: 20.09.18 13:03
Оценка:
Здравствуйте, ViTech, Вы писали:

VT>Здравствуйте, dipso, Вы писали:


D>>Прошу прощения, не все ответы прочитал, нет столько времени, но...

D>>Самый простой вариант — реализовать класс Tree пытаясь использовать
D>>нынешнию RAII идеологию. Пишу прямо в тегах, сильно не пинайте.

VT>Если m_parent типа weakptr_type(и это правильно), то зачем в Parent()/SetParent() используется ptr_type? Попробуйте изменить на weakptr_type.


D>>Нужно наследование от std::enable_shared_from_this.

D>>Конструктор по умолчанию не важен.Хочу наследовать от
D>>Tree. Включение против наследования не поможет.
D>>Интересуют конструкторы.
D>>В любом случае std::bad_weak_ptr.

VT>Я бы не стал наследоваться от такого Tree. Но если так надо... Пишите код, с которым возникают проблемы, чтобы было от чего отталкиваться. На предположениях далеко не уедешь .

Ничего говорить не буду, разводить холивары.Могло бы решить переопределение в классе new.
Но кто-то на sof сказал что это не консистентность в языке. Я люблю C++, но истинного RAII так и не получится.
Re[2]: RAII vs RAII
От: rg45 СССР  
Дата: 20.09.18 16:28
Оценка:
Здравствуйте, dipso, Вы писали:

D>Прошу прощения, не все ответы прочитал, нет столько времени, но...

D>Самый простой вариант — реализовать класс Tree пытаясь использовать
D>нынешнию RAII идеологию. Пишу прямо в тегах, сильно не пинайте.

  The Original Example
D>
D>template<typename T>
D>class Tree
D>{
D>public:

D>  using ptr_type = std::shared_ptr<T>;
D>  using weakptr_type = std::weak_ptr<T>;

D>Tree(ptr_type parent)
D>{
D>  SetParent(parent);
D>}

D>ptr_type Parent()
D>{
D>  return m_parent.lock();
D>} 

D>void SetParent(ptr_type parent) 
D>{
D>  m_parent = parent;

D>}

D>private:

D>weakptr_type m_parent;
D>std::vector<ptr_type> m_children;
D>};
D>


D>Нужно наследование от std::enable_shared_from_this.

D>Конструктор по умолчанию не важен.Хочу наследовать от
D>Tree. Включение против наследования не поможет.
D>Интересуют конструкторы.
D>В любом случае std::bad_weak_ptr.

Ну теперь хоть задача понятна более-менее

И сразу хочу отметить, что я вижу как раз то, о чем говорил здесь: http://rsdn.org/forum/cpp/7249960.1
Автор: rg45
Дата: 18.09.18
. А именно, не очень удачный дизайн. Судите сами: мы имеем проблему невозможности получения в конструкторе владеющего указателя на конструируемый класс. Вопрос: почему нам нужен этот указатель? А потому, что мы так запроектировали. А что нам мешает изменить этот дизайн? Да ничего!

Выбрасываем метод SetParent, а вместо него добавляем пару методов: AddChild и CreateChild. После чего юзабельность не только не ухудшается, а становится даже лучше. И исходная проблема испаряется как сон на заре:

https://ideone.com/HypKcm

template <typename T>
class Tree : public std::enable_shared_from_this<Tree<T>>
{
public:

  template<typename...Args>
  explicit Tree(Args&&...args) : m_data(std::forward<Args>(args)...) {}
  
  std::shared_ptr<Tree> AddChild(const std::shared_ptr<Tree>& child)
  {
    using base = std::enable_shared_from_this<Tree>;
    m_children.push_back(child);
    child->m_parent = base::shared_from_this();
    return child;
  }

  template<typename...Args>
  std::shared_ptr<Tree> CreateChild(Args&&...args)
  {
    return AddChild(std::make_shared<Tree>(std::forward<Args>(args)...));
  }

private:
  T m_data;
  std::weak_ptr<Tree> m_parent;
  std::vector<std::shared_ptr<Tree>> m_children;
};

int main()
{
  const auto root_ptr = std::make_shared<Tree<int>>();
  root_ptr->CreateChild(1)->CreateChild(11)->CreateChild(111);
  root_ptr->CreateChild(2)->CreateChild(21)->CreateChild(211);
}
--
Отредактировано 20.09.2018 16:45 rg45 . Предыдущая версия . Еще …
Отредактировано 20.09.2018 16:42 rg45 . Предыдущая версия .
Отредактировано 20.09.2018 16:35 rg45 . Предыдущая версия .
Отредактировано 20.09.2018 16:33 rg45 . Предыдущая версия .
Re[5]: RAII vs RAII
От: Erop Россия  
Дата: 02.10.18 07:45
Оценка:
Здравствуйте, rg45, Вы писали:

R>>>Зачем вообще может понадобиться владеющий указатель в конструторе? Что можно делать с владеющим указателем на объект, время жизни которого еще не началось? Ну, допустим, получили мы его, что дальше?


R>Сырой указатель на что, на конструируемый объект? И зачем может понадобиться передавать его в базовый класс, когда его можно там без труда вычислить? Разве что, при виртуальном наследовании? Тем более не понятно, зачем может понадобиться передавать в базовый класс владеющий указатель на конструируемый объект.


shared_ptr -- это не только владеющий, но и слабый. Легко может понадобиться для подписки на уведомления какие-нибудь, например...

Если клиентом подписки будет RAII, то придётся подписывемый объект из этого клиента выводить и мутить какие-то вирт. методы, или делать подписку в две стадии, или таки передавать в конструктор клиента подписки this на недоделанный объект...

Скажем, пусть у нас подписчик шаблонный, определяется типом сокета, к которому подписывется (прототип входа/выхода или std::function, например), и в конструктор получает сокет и коллбэк.
Удобно было бы сделать подписчик полем, и в его конструктор передать сокет и лямбду...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Отредактировано 02.10.2018 8:03 Erop . Предыдущая версия .
Re[6]: RAII vs RAII
От: Кодт Россия  
Дата: 02.10.18 10:06
Оценка:
Здравствуйте, Erop, Вы писали:

E>Если клиентом подписки будет RAII, то придётся подписывемый объект из этого клиента выводить и мутить какие-то вирт. методы, или делать подписку в две стадии, или таки передавать в конструктор клиента подписки this на недоделанный объект...


Вот это всё — лишний раз показывает, что очень зря в плюсах нет двухфазной инициализации из коробки. И каждый раз там, где она нужна, её велосипедят.
Перекуём баги на фичи!
Re[7]: RAII vs RAII
От: Erop Россия  
Дата: 02.10.18 10:43
Оценка:
Здравствуйте, Кодт, Вы писали:

К>Вот это всё — лишний раз показывает, что очень зря в плюсах нет двухфазной инициализации из коробки. И каждый раз там, где она нужна, её велосипедят.


Да она просто дороже. И её ничто не мешает на библиотеке сделать. Нет проблем.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re: RAII vs RAII
От: CEMb  
Дата: 04.10.18 03:05
Оценка:
Здравствуйте, dipso, Вы писали:

D>Но std::enable_shared_from_this::shared_from_this нельзя использовать в конструкТОРАХ.


D>Ладно у кого какие варианты7


Редкий случай, но если надо, я использую weak_ptr внутри класса на самого себя. Т.е. тот, кто создал объект, потом ему указатель прописывает, +1 строчка в функции. Раньше использовал shared_from_this, но это немного неочевидная штука, потому что shared_ptr создаётся снаружи и управление объектом поручать самому объекту немного неправильно (delete this посреди поля).
В идеальной ситуации сам объект не должен выдавать shared_ptr на себя. Т.е. надо пересмотреть архитектуру.
Re[4]: RAII vs RAII
От: dipso  
Дата: 04.10.18 17:19
Оценка:
Здравствуйте, ViTech, Вы писали:

VT>Здравствуйте, rg45, Вы писали:


R>>И сразу хочу отметить, что я вижу как раз то, о чем говорил здесь: http://rsdn.org/forum/cpp/7249960.1
Автор: rg45
Дата: 18.09.18
. А именно, не очень удачный дизайн. Судите сами: мы имеем проблему невозможности получения в конструкторе владеющего указателя на конструируемый класс. Вопрос: почему нам нужен этот указатель? А потому, что мы так запроектировали. А что нам мешает изменить этот дизайн? Да ничего!


VT>Ну как что мешает... Если перепроектировать, то становится не интересно. А как же полёт фантазии, муки творчества? Передать недостроенный this в конструктор базового класса, приватно наследовать интерфейс, возможно стать владельцем себя самого. Искать RAII в C++. Грустить, что его там нет. Выбрасывается целый пласт деятельности и переживаний. Скучно живёте, товарищи .


VT>Если всё перепроектировать, то можно дойти до чего угодно. Например, задаться вопросами: Tree уникально владеет своими children или нет? Т.е. может ли один child находиться одновременно в двух разных Tree (или ещё у кого-нибудь во владении вообще)? Точно ли тут нужен std::shared_ptr для children? И как следствие std::enable_shared_from_this для Tree. Всё же скатится в банальность .


Ну да, да, да.
Вот вариант двуфакторной инициализации. Мне важно ваше мнение.
Re[2]: RAII vs RAII
От: dipso  
Дата: 04.10.18 17:44
Оценка:
CEM>Редкий случай, но если надо, я использую weak_ptr внутри класса на самого себя. Т.е. тот, кто создал объект, потом ему указатель прописывает, +1 строчка в функции. Раньше использовал shared_from_this, но это немного неочевидная штука, потому что shared_ptr создаётся снаружи и управление объектом поручать самому объекту немного неправильно (delete this посреди поля).
CEM>В идеальной ситуации сам объект не должен выдавать shared_ptr на себя. Т.е. надо пересмотреть архитектуру.

Здесь проблема передечи своего this кому-то в базовом классе. Ну типа передать себя родителю. Поэтому, даже AddChild не поможет, поскольку enable_shared_from_this всё равно даст std::bad_weak_ptr.Т.е нуна чёб отработали все крнструктора. Потому и two-facktor-initialization. Вопрос — можно ли средствами языка заставить людей не создавать объекты на стеке. Ну всем же нужны std::shared_ptr's ...
Re[2]: RAII vs RAII
От: dipso  
Дата: 04.10.18 17:58
Оценка:
Здравствуйте, CEMb, Вы писали:

CEM>Здравствуйте, dipso, Вы писали:


D>>Но std::enable_shared_from_this::shared_from_this нельзя использовать в конструкТОРАХ.


D>>Ладно у кого какие варианты7


CEM>Редкий случай, но если надо, я использую weak_ptr внутри класса на самого себя. Т.е. тот, кто создал объект, потом ему указатель прописывает, +1 строчка в функции. Раньше использовал shared_from_this, но это немного неочевидная штука, потому что shared_ptr создаётся снаружи и управление объектом поручать самому объекту немного неправильно (delete this посреди поля).

CEM>В идеальной ситуации сам объект не должен выдавать shared_ptr на себя. Т.е. надо пересмотреть архитектуру.
Не надо пересматривать архитектуру в общем. Здесь просто языковая зоковыка которую надо обойти. Да, ту самую RAII, о которой говорят на каждом сиплюсплюс углу, заменить на двухфакторную инициализацию, у которой самой рогожки и ножки, если вы адепт чистого пламенного "встандартепрописсанного" два плюса)))
Re[3]: RAII vs RAII
От: dipso  
Дата: 04.10.18 19:22
Оценка:
Здравствуйте, dipso, Вы писали:

D>Здравствуйте, CEMb, Вы писали:


CEM>>Здравствуйте, dipso, Вы писали:


D>>>Но std::enable_shared_from_this::shared_from_this нельзя использовать в конструкТОРАХ.


D>>>Ладно у кого какие варианты7


CEM>>Редкий случай, но если надо, я использую weak_ptr внутри класса на самого себя. Т.е. тот, кто создал объект, потом ему указатель прописывает, +1 строчка в функции. Раньше использовал shared_from_this, но это немного неочевидная штука, потому что shared_ptr создаётся снаружи и управление объектом поручать самому объекту немного неправильно (delete this посреди поля).

CEM>>В идеальной ситуации сам объект не должен выдавать shared_ptr на себя. Т.е. надо пересмотреть архитектуру.
D>Не надо пересматривать архитектуру в общем. Здесь просто языковая зоковыка которую надо обойти. Да, ту самую RAII, о которой говорят на каждом сиплюсплюс углу, заменить на двухфакторную инициализацию, у которой самой рогожки и ножки, если вы адепт чистого пламенного "встандартепрописсанного" два плюса)))
Зто уже политический вопрос, надеюсь, мы будем от них долеки.
Re[3]: RAII vs RAII
От: CEMb  
Дата: 08.10.18 04:25
Оценка:
Здравствуйте, dipso, Вы писали:

D>Здесь проблема передечи своего this кому-то в базовом классе. Ну типа передать себя родителю. Поэтому, даже AddChild не поможет, поскольку enable_shared_from_this всё равно даст std::bad_weak_ptr.Т.е нуна чёб отработали все крнструктора. Потому и two-facktor-initialization. Вопрос — можно ли средствами языка заставить людей не создавать объекты на стеке. Ну всем же нужны std::shared_ptr's ...


//...
private:
    Child();
friend shered_ptr<Child>(); // или как-то так, не помню.

//...
template <typename Child> void Parent::Creare ()
{
    shared_prt<Child> child = make_shared<Child>();
    if (child)
    { //..
    }
}

Примерно так?
Конструкторы все отработали, указатель у родителя.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.