Здравствуйте, 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);
}