Как лучше всего выставить частное наследование базовому классу?

Я проектирую иерархию объектов, в которой базовый класс всех объектов 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;
}

Этот подход выглядит немного грязно, потому что я храню ссылку на производный класс в базовом классе (я никогда раньше этого не видел). Это хорошая практика? Существуют ли более эффективные способы сохранения дочернего владения в производном классе при обработке общего обслуживания детей в базовом классе?

0

Решение

Вы почти там. Не храните ссылку на DERIVED_T в Node, Просто пиши:

     auto derivedThis& = *static_cast<DERIVED_T*>(this);

в каждой из функций, которые нуждаются в этом. (Или же const DERIVED_T* при необходимости).

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]