Я моделирую общую древовидную структуру, имея класс для каждого узла с указателями на родителя, первого потомка и первого брата, а также указатель на последнего брата (не нужно, но полезно). К этому я добавляю некоторые дополнительные данные atd. Моя текущая реализация:
class TreeNode {
typedef boost::shared_ptr<TreeNode> Ptr;
typedef boost::weak_ptr<TreeNode> WPtr;
WPtr p2parent; ///< pointer to the parent node (NULL in the root)
Ptr p2sibling; ///< pointer to the first sibling (or NULL)
Ptr p2child; ///< pointer to the first child (or NULL)
WPtr p2lastChild; ///< pointer to the last child (not strictly needed)
};
Как видите, я использую shared_ptr для одноуровневого и дочернего элемента, поэтому можно удалить все дерево, просто удалив его корень. Что касается указателя на родителя, я знаю, что не должен использовать shared_ptr, так как это создаст циклы, поэтому мне придется выбирать между слабым_птром и необработанным указателем (TreeNode *) - есть мысли?
Для (необязательного) указателя на последний дочерний элемент, выбор между слабым_птр, общим_птр и необработанным указателем - что является лучшим выбором, чтобы сделать весь класс внутренне непротиворечивым?
Наконец, у меня есть пара итераторов по структуре, например, итератор atd для глубины. Какие указатели должны использовать итераторы внутри: необработанный указатель, weak_ptr или shared_ptr? Каковы преимущества трех подходов?