I wanted to use the composite pattern in C++ but I encountered a problem in doing so.
My code looks like that:
class Component
{
protected:
Component* parent = nullptr;
};
class Leaf : public Component
{};
class Composite : public Component
{
public:
typedef std::unique_ptr<Component> ComponentPtr;
public:
void addChild(ComponentPtr child)
{
child->parent = this;
// ...
}
auto removeChild(const Component& child) -> ComponentPtr;
};
The problem is that in the addChild method the protected parent member can't be accessed. I just have learned that an instance A can access the protected members of an instance B if and only if A and B are of the same type or B is derived from A. So the code shown above doesn't work for obvious reasons.
Now I ask myself how to solve the problem of not being able to access the parent member. Currently I can think of some possibilities:
- Use a friend class/function/method to access the parent member.
- Make the parent member public or provide a public getter/setter method.
- Don't use the composite pattern. Instead have only a Component class that has both a parent and children.
I'm not too fond of the second option because setting the parent should not be part of the public API.
When using the third option every component would be a composite. Whether this is to be considered a bad thing probably depends on what the code is used for. In my case it wouldn't be so bad. If an object isn't supposed to have children I just won't add any.
What do you think? Are there any other alternatives?
Edit:
Unfortunately I have left out some relevant implementation details. As this caused some misunderstandings I would like to add the missing details here:
class Composite : public Component
{
/* some code ommited */
public:
void addChild(ComponentPtr child)
{
child->parent = this;
children.push_back(std::move(child));
}
/* some code ommited */
private:
std::vector<ComponentPtr> children;
};