I have an abstract base class
class IThingy
{
virtual void method1() = 0;
virtual void method2() = 0;
};
I want to say – “all classes providing a concrete instantiation must provide these static methods too”
I am tempted to do
class IThingy
{
virtual void method1() = 0;
virtual void method2() = 0;
static virtual IThingy Factory() = 0;
};
I know that doesnt compile, and anyway its not clear how to use it even if it did compile. And anyway I can just do
Concrete::Factory(); // concrete is implementation of ITHingy
without mentioning Factory in the base class at all.
But I feel there should be some way of expressing the contract I want the implementations to sign up to.
Is there a well known idiom for this? Or do I just put it in comments? Maybe I should not be trying to force this anyway
Edit: I could feel myself being vague as I typed the question. I just felt there should be some way to express it. Igor gives an elegant answer but in fact it shows that really it doesn’t help. I still end up having to do
IThingy *p;
if(..)
p = new Cl1();
else if(..)
p = new Cl2();
else if(..)
p = new Cl3();
etc.
I guess reflective languages like c#, python or java could offer a better solution
The problem that you are having is partly to do with a slight violation a single responsibility principle. You were trying to enforce the object creation through the interface. The interface should instead be more pure and only contain methods that are integral to what the interface is supposed to do.
Instead, you can take the creation out of the interface (the desired
virtual staticmethod) and put it into a factory class.Here is a simple factory implementation that forces a factory method on a derived class.
Usage:
By derinving from
Factory<TClass, TInterface>, the derived class is forced to have a CreateInternal method by the compiler. Not deifining it will result in an error like this: