Search code examples
c#c++oopdesign-patternscomposite

Composite pattern in C++ and C# - protected virtual methods


How can I add a protected virtual method in the "Component" class, so that it can be called from the "Composite"?

As an concrete example, look at the code below, and please tell me how to avoid the compiler error in DxCompositeShape.ComputeSize.

abstract class DxShape // this is the Component
{
    public abstract void Paint();
    protected abstract void ComputeSize();
}

class DxCompositeShape : DxShape // this is the Composite
{
    public readonly IList<DxShape> Shapes = new List<DxShape>();

    public override void Paint()
    {
        this.ComputeSize();
    }

    protected override void ComputeSize()
    {
        foreach (DxShape sh in Shapes)
        {
            sh.ComputeSize(); // compiler error CS1540
        }
        // and some other logic here
    }
}

EDIT: I modified my sample, so I have ComputeSize instead of Init (people assume that Init can always be called in a constructor).


Solution

  • Create a non-virtual function Initialise() in the base class that calls Init

    eg:

    abstract class DxShape
    {
        protected void Initialise()
        {
            Init();
        }
        protected abstract void Init();
        //...
    }
    

    As pointed out in the comments below, Initialise must be made either public or static (only in C#), it may remain protected in C++. In C++ you could then make Init private and only access it via calls to Initialise. See non-virtual interface http://en.wikipedia.org/wiki/Non-virtual_interface_pattern