Я проектирую иерархию объектов, в которой базовым классом всех объектов является Node
, который, как ожидается, будет подклассифицирован. Подклассы Node
будут содержать дочерние элементы, но тип ребенка может варьироваться от одного подкласса к другому.Как лучше всего открыть частное наследство базовому классу?
Я реализую право собственности на дочерние элементы, наследуя от класса Owner<>
, который является только оберткой для std::vector
. Я хочу разоблачить это право собственности на базовый класс (но никто другой), потому что есть много повторений в отношении добавления и удаления дочерних элементов. Так что я пришел с этим:
#include <vector>
using namespace std;
//Class to contain child items
template <typename T>
struct Owner {
vector<T> children;
};
//Types of children that can be owned by nodes in the hierarchy
struct ChildType1{};
struct ChildType2{};
struct ChildType3{};
//Node base class
template <typename DERIVED_T>
struct Node {
Node(DERIVED_T& _derivedThis):
derivedThis(_derivedThis)
{}
template <typename ITEM_T>
void AddItem() {
/*Possibly do a lot of pre-checks here before adding a child*/
derivedThis.Owner<ITEM_T>::children.emplace_back();
}
//Reference to the most-derived subclass instance
DERIVED_T& derivedThis;
};
//A possible subclass of Node
struct DerivedNode:
private Owner<ChildType1>,
private Owner<ChildType2>,
public Node<DerivedNode>
{
friend struct Node<DerivedNode>;
DerivedNode():
Node(*this)
{}
};
int main() {
DerivedNode d;
d.AddItem<ChildType1>();
d.AddItem<ChildType2>();
//d.AddItem<ChildType3>(); //Fails to compile (intended behavior; DerivedNode should not own ChildType3 objects)
return 0;
}
Этот подход чувствует себя немного грязный, потому что я хранить ссылку на производный класс в базовом классе (я никогда не видел этого раньше). Это хорошая практика? Существуют ли более эффективные способы хранения дочерней собственности в производном классе при обращении с общим обслуживанием ребенка в базовом классе?
Вы когда-нибудь читали о [CRTP] (https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern)? –
Думаю, я только прочитал первый абзац в Википедии. Использование 'static_cast (это)' никогда не приходило мне ... спасибо. –
Carlton