Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Extending the enumerations

Tags:

c++

enums

factory

I have a design problem.

I have a polymorphic structure with an interface A (abstract one) and a workflow implemented in class W which uses the interface A without knowing the derived classes. This is implemented in DLL1 and I have a factory interface F capable of returning A*. In DLL2, I have the concrete implementations of A, which could be A1, A2 etc. and a factory implementation F1 capable of creating A1 and A2 instances.

The factory interface which I have is something like this.

enum ObjectType{typeA1, typeA2};

class F
{
    public:
    A* create(enum ObjectType) = 0;
}

Some client class which knows both DLL1 and DLL2 will give me the concrete object type.

But this is ugly since I will have to know the possible types of the concrete classes upfront when I write my DLL1. And this almost defeats my purpose of the polymorphic design. I don't want to do this.

The alternative option which I can think of is to use strings, instead of the enumeration. But, I like to avoid strings as they are not type-safe and are prone to errors. I wish I had a chance to extend the enums by inheritance, just like the classes.

My questions :

Is there a better way out? Is extension of enums possible in C++11? (I don't have it now, though)

like image 211
PermanentGuest Avatar asked Jun 23 '26 23:06

PermanentGuest


1 Answers

You can modify your abstraction to allow the user of interface A to also provide the particular factory that creates it. (instead of providing an enum).

// In DLL1
class AbstractF {
public:
    virtual A * create () = 0;
};

template <typename ConcreteA>
class ConcreteF : public AbstractF {
public:
    A * create () { return new ConcreteA; }
};

Now, each ConcreteF<> would need to be passed into code to DLL1 for those parts of the framework that need to create the right concrete instance of A. Thus, the framework user must inform the framework which of A1 or A2 to create not by passing in an ObjectType, but by passing in the correct ConcreteF (namely ConcreteF<A1> or ConcreteF<A2>).

like image 158
jxh Avatar answered Jun 25 '26 21:06

jxh



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!