Сообщение Re[2]: RAII vs RAII от 20.09.2018 16:28
Изменено 20.09.2018 16:42 rg45
Re[2]: RAII vs RAII
Здравствуйте, dipso, Вы писали:
D>Прошу прощения, не все ответы прочитал, нет столько времени, но...
D>Самый простой вариант — реализовать класс Tree пытаясь использовать
D>нынешнию RAII идеологию. Пишу прямо в тегах, сильно не пинайте.
D>Нужно наследование от std::enable_shared_from_this.
D>Конструктор по умолчанию не важен.Хочу наследовать от
D>Tree. Включение против наследования не поможет.
D>Интересуют конструкторы.
D>В любом случае std::bad_weak_ptr.
Ну теперь хоть задача понятна более-менее
И сразу хочу отметить, что я вижу как раз то, о чем говорил здесь: http://rsdn.org/forum/cpp/7249960.1
https://ideone.com/HypKcm
D>Прошу прощения, не все ответы прочитал, нет столько времени, но...
D>Самый простой вариант — реализовать класс Tree пытаясь использовать
D>нынешнию RAII идеологию. Пишу прямо в тегах, сильно не пинайте.
The Original Example | |
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
. А именно, не очень удачный дизайн. Судите сами: мы имеем проблему невозможности получения в конструкторе владеющего указателя на конструируемый класс. Вопрос: почему нам нужен этот указатель? А потому, что мы так запроектировали. А что нам мешает изменить этот дизайн? Да ничего!Дата: 18.09.18
https://ideone.com/HypKcm
template <typename T>
class Tree : public std::enable_shared_from_this<Tree<T>>
{
public:
Tree() = default;
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>>(0);
root_ptr->CreateChild(1)->CreateChild(11)->CreateChild(111);
root_ptr->CreateChild(2)->CreateChild(21)->CreateChild(211);
}
Re[2]: RAII vs RAII
Здравствуйте, dipso, Вы писали:
D>Прошу прощения, не все ответы прочитал, нет столько времени, но...
D>Самый простой вариант — реализовать класс Tree пытаясь использовать
D>нынешнию RAII идеологию. Пишу прямо в тегах, сильно не пинайте.
D>Нужно наследование от std::enable_shared_from_this.
D>Конструктор по умолчанию не важен.Хочу наследовать от
D>Tree. Включение против наследования не поможет.
D>Интересуют конструкторы.
D>В любом случае std::bad_weak_ptr.
Ну теперь хоть задача понятна более-менее
И сразу хочу отметить, что я вижу как раз то, о чем говорил здесь: http://rsdn.org/forum/cpp/7249960.1
Выбрасываем метод SetParent, а вместо него добавляем пару методов: AddChild и CreateChild. После чего юзабельность не только не ухудшается, а становится даже лучше. И исходная проблема испаряется как сон на заре:
https://ideone.com/HypKcm
D>Прошу прощения, не все ответы прочитал, нет столько времени, но...
D>Самый простой вариант — реализовать класс Tree пытаясь использовать
D>нынешнию RAII идеологию. Пишу прямо в тегах, сильно не пинайте.
The Original Example | |
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
. А именно, не очень удачный дизайн. Судите сами: мы имеем проблему невозможности получения в конструкторе владеющего указателя на конструируемый класс. Вопрос: почему нам нужен этот указатель? А потому, что мы так запроектировали. А что нам мешает изменить этот дизайн? Да ничего!Дата: 18.09.18
Выбрасываем метод SetParent, а вместо него добавляем пару методов: AddChild и CreateChild. После чего юзабельность не только не ухудшается, а становится даже лучше. И исходная проблема испаряется как сон на заре:
https://ideone.com/HypKcm
template <typename T>
class Tree : public std::enable_shared_from_this<Tree<T>>
{
public:
Tree() = default;
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>>(0);
root_ptr->CreateChild(1)->CreateChild(11)->CreateChild(111);
root_ptr->CreateChild(2)->CreateChild(21)->CreateChild(211);
}