Справочная информация:
Итак, я портировал часть своего старого Java-кода на C ++, и я столкнулся с проблемой, которая затрудняет работу. Мой проект использует древовидную структуру данных для представления иерархии узлов для 3D-анимации.
Java
public final class Node {
private final Node mParent;
private final ArrayList<Node> mChildren;
//private other data, add/remove children / parents, etc ...
}
В Java довольно просто создать дерево, которое позволяет модифицировать и т. Д.
Проблема:
Я сталкиваюсь с проблемами, связанными с C ++, невозможно легко добавить массивы без выделения вручную нового фрагмента памяти и перемещения существующих, поэтому я переключился на std::vector
. У векторов есть проблема делать то, что я только что описал, внутренне делая любые указатели на элементы там недействительными. Поэтому, если вы не хотите использовать указатели, вам нужен способ их поддержки, чтобы память, содержащая фактические узлы, не двигалась. Я считаю, что вы можете использовать std::shared_ptr
/ std::unique_ptr
, чтобы обернуть узлы в std::vector
, и я попытался поиграть с этим подходом, но он становится довольно громоздким. Другим вариантом было бы иметь класс «tree», который оборачивает класс узла и является интерфейсом для его манипулирования, но чем (для моего случая использования) было бы довольно раздражающе иметь дело с обрезкой веток и превращением их в собственные деревья и возможно прикрепление разных веток.
Большинство примеров, которые я вижу в Интернете, представляют собой двоичные деревья, которые имеют 2 узла, а не являются динамическими, или они содержат много комментариев об утечках памяти / и т. Д. Я надеюсь, что есть хорошая альтернатива C ++ коду java, показанному выше (без утечки памяти) вопросы и т. д.). Также я не буду заниматься ЛЮБОЙ сортировкой, цель дерева - поддерживать иерархию, чтобы не сортировать ее.
Честно говоря, я действительно не уверен, в каком направлении идти, я провел последние 2 дня, пробуя разные подходы, но ни один из них не "чувствует" себя хорошо, и, как правило, им действительно неудобно управлять, любая помощь будет признательна!
Edit:
Редактирование того, почему shared_ptrs громоздки:
class tree : std::enable_shared_from_this<tree> {
std::shared_ptr<tree> parent;
std::vector<std::shared_ptr<tree>> children;
public:
void set_parent(tree& _tree) {
auto this_shared_ptr = shared_from_this();
if (parent != nullptr) {
auto vec = parent->children;
auto begin = vec.begin();
auto end = vec.end();
auto index = std::distance(begin, std::find_if(begin, end, [&](std::shared_ptr<tree> const& current) -> bool {
return *current == this_shared_ptr;
}));
vec.erase(std::remove(begin, end, index), end);
}
parent = std::shared_ptr<tree>(&_tree);
if (parent != nullptr) {
parent->children.push_back(this_shared_ptr);
}
}
};
работа с указателями, как указано выше, становится довольно многословной, и я надеялся на более простое решение.