enum class Color { RED, BLACK };
enum class TreeModel { AVL, RED_BACK, SPLAY }
struct BasicNode {
BasicNode* left;
BasicNode* right;
BasicNode* parent;
};
struct SplayNode : BasicNode {
}
struct RBNode : BasicNode {
Color color;
};
struct AVLNode : BasicNode {
unsigned int height;
};
....
???? node_;
if (condition == 1)
node = new AVLNode;
else if (condition == 2)
node = new RBNode;
else
node = new SplayNode;
как сделать выбор типа структуры
Я только начал изучать C++ и не знаю, как выбрать тип структуры в зависимости от параметра шаблона класса, когда я создаю класс.
«я только начал изучать c++...» Хорошая книга по c++
Чего вы надеетесь достичь, сделав деревья RB и деревья AVL одним классом? Это кажется мне ужасной, ужасной идеей.
Каковы условия отбора? То есть какова связь между параметром шаблона и объявленными структурами? Как вы собираетесь выбирать одну из структур вручную (на бумаге)? На данный момент вопрос неясен.
используя Node = ????
@vansergh Мы не знаем, для чего вам нужен псевдоним Node
. Поэтому нет возможности ответить на ваш вопрос. То есть Node = ????
недостаточно для ответа на ваш вопрос.
псевдоним будет использоваться для возврата методов и в качестве параметра метода.
Вы можете использовать constexpr if
. Есть и другие способы. Но для этого вам нужно будет уточнить вопрос.
??КАК???ТИП?? узел_; если (условие == 1) узел = новый AVLNode; иначе, если (условие == 2) узел = новый RBNode; еще узел = новый SplayNode;
@vansergh Вы можете просто написать BasicNode* node;
, так как это основа всех трех показанных структур.
и я смогу использовать параметры AVLNode? узел.высота?
@v Вам придется использовать node->height
, так как теперь это указатель. Также я бы порекомендовал продолжить чтение книг, на которые я дал ссылку, поскольку все это будет описано в одной из глав.
автоматический узел = новый AVLNode;
@vansergh auto
это не то, что ты думаешь. Это тип заполнителя. Тип auto
выводится из инициализатора. Посмотрите книги, поскольку эти книги помогут вам прояснить ваш вопрос, и тогда вам будет легче увидеть проблему с данным кодом.
Узел BasicNode* = новый AVLNode; узел-> высота = 10; // 'struct BasicNode' не имеет элемента с именем 'height'
У этих деревьев гораздо меньше общего, чем вы думаете. Вы, вероятно, заметите это, если сначала реализуете их отдельно.
Все ваши узлы происходят от BasicNode
, поэтому вы можете иметь BasicNode * node
, а затем присвоить node
new AVLNode
, new RBNode
и т. д., при этом используя необработанные указатели в боте, рекомендованные в современном C++. Вместо этого используйте интеллектуальный указатель.
std::unique_ptr?
или может быть союз?
или станд::вариант?
@vansergh Обратите внимание, что это не дискуссионный форум. Все подробности должны быть указаны в вашем вопросе. Также вы можете просто записать предыдущие три комментария (unique_ptr, Union и т. д.) в один комментарий. Вы не уточняете свой вопрос, а спрашиваете о случайных конструкциях С++. Это не имеет никакого отношения к вопросу.
Эта конструкция в корне ошибочна. AVLNode::left
теперь BasicNode*
, но должно быть AVLNode*
. Вы не можете иметь смешанные деревья.
enum class Color { BLACK, RED };
enum class TransplantMode { DEFAULT, LEFT, RIGHT };
enum class TraverseMode { CONTINUOUS, RECURSIVE };
enum class TreeModel { SPLAY, RED_BLACK, AVL };
....
template <class DataType>
class BaseNode {
public:
DataType data;
};
template <class DataType>
class SplayNode : public BaseNode<DataType> {
public:
SplayNode<DataType>* left;
SplayNode<DataType>* right;
SplayNode<DataType>* parent;
};
template <class DataType>
class AVLNode : public BaseNode<DataType> {
public:
AVLNode<DataType>* left;
AVLNode<DataType>* right;
AVLNode<DataType>* parent;
unsigned int height;
};
template <class DataType>
class RBNode: public BaseNode<DataType> {
public:
RBNode<DataType>* left;
RBNode<DataType>* right;
RBNode<DataType>* parent;
unsigned int height;
};
....
template <class DataType, class NodeType, const TreeModel model>
class BaseTree {
....
}
template <class DataType>
class RBTree : private BaseTree<DataType, RBNode<DataType>, TreeModel::RED_BLACK> {
....
};
template <class DataType>
class AVLTree : private BaseTree<DataType, AVLNode<DataType>, TreeModel::AVL> {
....
};
template <class DataType>
class SplayTree : private BaseTree<DataType, SplayNode<DataType>, TreeModel::SPLAY> {
....
};
Не обращая внимания на всю эту болтовню и просто отвечая на ваш вопрос, как лучше всего создать переменную, которая может содержать несколько типов.
Когда я нахожусь в этой ситуации; если то, что у вас есть в качестве узла, является локальной переменной, я перемещаю остальную часть кода в функцию шаблона (иногда лямбда), чтобы я мог передать нужный мне тип. Если бы ваш узел был переменной-членом, я бы сделал его объединением или разновидностью типов, которыми он мог бы быть. Здесь я бы использовал объединение, поскольку все возможные типы происходят от одной и той же базы, и было бы сложнее получить доступ к членам базового класса, если бы он был разновидностью.
Каков ожидаемый результат? Также нам нужен минимальный воспроизводимый пример