lundi 6 janvier 2020

Suitable design-pattern for sub-object that can have multiple types in C++?

I wish to implement the choice and case statements of https://tools.ietf.org/html/rfc6020 in C++11. In short, suppose:

  • an Entity object has zero or more Choice objects
  • a Choice has zero or more Case objects
  • a Case has zero or more Choice objects

One implication of the requirements above is that a Choice either belongs to an Entity or Case object.

The following satisfies most of the above requirements:

#include <list>

class Entity
{
    public:
        std::list<Choice> myChoices;   // child nodes (cardinality: 0..n)
};

class Choice
{
    public:
        /* ??? */         mOwner;      // parent node (cardinality: 1   ); type is Entity* or Case*
        std::list<Case>   myCases;     // child nodes (cardinality: 0..n)
};

class Case
{
    public:
        Choice*           myOwner;     // parent node (cardinality: 1   )
        std::list<Choice> myChoices;   // child nodes (cardinality: 0..n)
};

Question:

What would be an elegant solution for representing data member Choice::myOwner? Is there a known design-pattern that is a good match to this problem?

Possible approach (1):

Would the use of an abstract class be overkill? For example:

class ChoiceParent
{
    ~ChoiceParent() = 0;
    virtual bool isEntity() const { return false; }
    virtual bool isCase() const { return false; }
};

ChoiceParent::~ChoiceParent()
{ }

class ParentEntity : public ChoiceParent
{
    bool isEntity() const override { return true; }
};

class ParentCase : public ChoiceParent
{
    bool isEntity() const override { return true; }
};

class Choice
{
    public:
        ChoiceParent*     mOwner;
        std::list<Option> myOptions;
};

Possible approach (2):

Use boost::variant?

#include <boost/variant.hpp>

class Choice
{
    public:
        using TypeVariant = boost::variant<Entity, Case>;      

        TypeVariant       mAmbiguousOwner;
        std::list<Option> myOptions;
};

Aucun commentaire:

Enregistrer un commentaire