Jump to content

  • Log In with Google      Sign In   
  • Create Account

#ActualBurrickSlayer

Posted 06 October 2013 - 11:34 AM

Hello all,

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 can't decide on the first option because I've hardly used friends in C++ so far.

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;
};

#1BurrickSlayer

Posted 05 October 2013 - 11:04 AM

Hello all,

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 can't decide on the first option because I've hardly used friends in C++ so far.

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?

PARTNERS