The problem
Imagine having a base class, in a framework, that defines several pure virtual methods, which is effectively an interface. Users of this class inherit from it and implement its method as usual.
What I'm trying to obtain is provide a mechanism to the framework for instantiating derived class via an uniform factory method that return an instance of the derived class.
The try
I thought of putting a static base* get_one() method inside the base class to be reimplemented, but of course, being static, it can't be virtual.
The goal
The final goal is to provide a base class for a so-called driver, so that users can write their own implementations and the framework can, when asked to do so, return device instances using that particular driver.
A simple (and I suppose common) approach is to "register" an instance of the derived class at the (abstract) base class, which then serves as a factory. You may then decide whether the driver shall be a singleton or whether the instance is a "template" from which a copy is drawn every time a caller request a driver.
A simple implementation could look as follows:
// Framework part:
class Driver {
public:
static Driver* getDriver() {
return driver; // return the instance (or make a copy, if desired)
};
static void registerDriver(Driver *driver) {
Driver::driver = driver;
}
private:
static Driver *driver;
};
Driver *Driver::driver = nullptr;
// Customization part:
class MyDriver : public Driver {
};
MyDriver mySingleDriver;
int main()
{
Driver::registerDriver(&mySingleDriver);
return 0;
}
In production, you'd probably use managed pointers and implement a more sophisticated "singleton" approach. But the principle should be clear...
Related
I am trying to add a plugin capability to my C++ codebase. The difficulty arises because the plugins need to contain plumbing the plugin writer shouldn't be aware of (thus keeping the include file simple).
So, this is the setup:
"PluginBase.h". This is the class the plugin would inherit from.
class PluginBase {
virtual void PluginProcess() = 0; // the plugin-specific capability
};
"PluginPlumbing.h". The class that contains the plumbing.
class PluginPlumbing : public PluginBase {
void PlumbingFunction() {
// Some stuff
PluginProcess();
// Some more stuff
}
};
The outer framework code would (by loading the DLL/so of the plugin) acquire a pointer to a PluginPlumbing class instance, and then call PlumbingFunction() on it.
However, the conundrum I have is, I can't just upcast a PluginBase pointer I get from the DLL/so to a PluginPlumbing pointer as it clearly doesn't actually inherit from PluginPlumbing. And I can't have the plugin inherit from PluginPlumbing, because then I'm back at square one of exposing the plumbing to the plugin writer.
The only solution I can imagine is that instead of nicely inheriting, the PluginBase and the PluginPlumbing are entirely separate classes. The PluginBase would be instantiated by the DLL/so, and the PluginPlumbing instance would be instantiated by the framework, and handed that PluginBase pointer so it can make the plumbing calls. Is that the only solution to go about it?
If you want to expose some functionality from your plugins to external software you definitely have to provide some interface for that.
In your example you provided PluginBase interface with PluginProcess() function, so, any other user of your PluginBase interface can call it without having to care about its implementation.
If you need another interface with another method - do it the same way.
class PluginPlumbing {
public:
virtual void PlumbingFunction() = 0;
};
And hide the implementation in your DLL implementation:
class PluginPlumbingImpl : public PluginPlumbing {
public:
void PlumbingFunction() override {
// do the stuff
}
}
If it needs additional parameters - also pass it as abstract interface classes or POD structures. You should also have some declaration for your plugin function which will create exact instances for your interface implementations (which should be accessible by users of your plugins).
To summarize this, you should have something like that:
// myplugininterface.h
// this header will be exposed to plugin implementors and
// plugin consumers
class IMyPluginClass1 {
public:
virtual void func1() = 0;
virtual void func2() = 0;
}
// another interface, ties together other functionality
class IMyPluginClass2 {
public:
virtual void func1() = 0;
// you can even pass around your interface classes
virtual void doSomethingWithAnotherObject(IMyPluginClass1 *obj) = 0;
// or use "factory" methods to create objects
virtual IMyPluginClass1 *createObject() = 0;
}
// this is functions implemented by a plugins, they should create
// instances for your plugin objects
// you could do them as a static methods of your classes if you don't
// plan to expose that as C compatible plugins
IMyPluginClass1 *createObject1();
IMyPluginClass2 *createObject2();
// mycoolplugin.cpp
// specific implementation of your plugin, you or someone else
// compile this to plugin DLL
#include "myplugininterface.h"
class IMyPluginClass1Impl : public IMyPluginClass1 {
public:
IMyPluginClass1Impl() :
myMyValue(100500)
{}
void func1() override {
// implement
}
void func2() override {
// implement
}
private:
// you can have any private or even public members in your implementation
int mMyValue;
};
class IMyPluginClass2Impl : public IMyPluginClass2 {
public:
void func1() override {
// implement
}
void doSomethingWithAnotherObject(IMyPluginClass1 *obj) override {
// implement
// but don't assume you can cast IMyPluginClass1 to
// something specific, because it might be not yours implementation
// it depends on how carefully you design your interfaces and
// explain to plugin writers what is allowed and what is not
}
IMyPluginClass1 *createObject() {
// be careful with that, in that case you MUST declare
// virtual destructor as a part of your interface class
return new IMyPluginClass1Impl();
}
};
IMyPluginClass1 *createObject1() {
return new IMyPluginClass1Impl();
}
IMyPluginClass2 *createObject2() {
return new IMyPluginClass2Impl();
}
And users of your plugin can use it only by including myplugininterface.h and
obtaining addresses of create functions (this is platform dependent).
Keep in mind, that if you return instances created by new and allow
users of your plugins to delete objects created like that - you must
declare virtual destructor for your interface classes.
This is a general approach. It has some pitfalls when you have hierarchy for
your plugin objects, you cant share common implementation for your abstract
classes without putting some additional effort (assuming you don't want to have copypasta)
I have a several server programs which have a bunch of common code, but differ in a few child class implementations. I use the abstract factory-like pattern something like this:
int main(int argc, char **argv) {
Factory *factory = new Program1Factory();
ServerThread theServer(factory); // inject the dependencies
theServer.start();
}
Factory is a pure abstract class, composed of the various bits I need to obtain the methods which have to vary from program to program. It looks roughly like this:
class Factory {
public: virtual foo *getFooThing() = 0;
public: virtual bar *getBarThing() = 0;
};
The concrete declaration and implementation for one program might look like this:
class Program1Factory : public Factory {
public: virtual foo *getFooThing() { return new Program1Foo(); }
public: virtual bar *getBarThing() { return new Program1Bar(); }
};
This worked fine until I got to a bunch of methods which themselves are child classes of a library over which I have no control.
In that library, the constructors of each of the classes require the data to be processed to be provided in the constructor! But my program does not yet have the data; it's just starting up and declaring its factory. Only once all the methods are set up and the threads start, do my server programs receive transactions which are the input to the constructors.
That is to say, in the example above, I cannot simply say:
return new Program1Bar()
because the class from which Program1Bar is derived only has a constructor that looks like
Program1Bar(string *inputString, string *outputString)
I don't have those values at the time my factory is instantiated.
I need to somehow create a pointer to the concrete class I want, store that pointer in my factory, and -- the hard part I cannot figure out -- instantiate (call the constructor) for those classes when data finally arrives.
How can I go about this?
With those restrictions your Program1Bar class cannot be a subclass of the 3rd party library. Hard to talk abstract, but one suggestion would be for you to define a class like Task1Bar which is a subclass of your 3rd party library.
Then somewhere inside ProgramBar1::someMethod you can make your call to new Task1Bar. If you need the 3rd party library to persist across methods you can always define a member Task1Bar* task1 inside your Program1Bar class.
Just a suggestion, As I said, hard to define in the abstract.
Good day to you all...
I'm working on a complex project on my company which I use some wringled Factory Design pattern in the project. Omiting the details; I have some classes (I call them "Devices") which can only be created by "Readers":
class DeviceBase // this is a virtual base class
{
public:
//some stuff
friend class ReaderBase; // this is OK and necessary I guess?
private:
DeviceBase(); // cannot create a device directly
//some more stuff
}
class Device1: public DeviceBase // some extended device
{
public:
//some stuff
private:
//some more stuff
}
class Device2: public DeviceBase // some other extended device
{
public:
//some stuff
private:
//some more stuff
}
Now the "Reader", which happens to be factory for devices:
class ReaderBase
{
private:
DeviceBase[] _devices; // to keep track of devices currently "latched"
public:
// some other methods, getters-setters etc ...
// this method will create the "Devices" :
virtual bool PollforDevice ( DeviceType, timeout) = 0;
}
Now, this is my factory class; but it's (as you can see) pure virtual. I have special Readers inherit from this one:
class InternalReader: public ReaderBase
{
public:
// define other inherited methods by specifics of this reader
bool PollforDevice( DeviceType dt, timeout ms)
{
switch(dt)
{
case Device1: { /* create new device1 and attach to this reader */ } break;
case Device2: { /* create new device2 and attach to this reader */ } break;
}
// show goes on and on...
}
}
class ExternalReader: public Reader
{
public:
// define other inherited methods by specifics of this reader
bool PollforDevice( DeviceType dt, timeout ms)
{
switch(dt)
{
case Device1: { /* create new device1 and attach to this reader */ } break;
case Device2: { /* create new device2 and attach to this reader */ } break;
}
// show goes on and on...
}
}
The reason I use this pattern is: I'm writing for a system that can have multiple of these "readers" attached at the same time and I must use them all at the same time.
And these "Devices": I can make theirs constructor public too, and everyone would be happy; but I want to make sure that they are not created by the code writers themselves (to make sure other coders of it)
Now the questions:
Should I explicitly declare in every "Device" that ReaderBase is a friend? Or just declaring at the base "DeviceBase" should be enough?
Should I explicitly put in every "Device" that the "Readers" inherited from the "ReaderBase" are also friends of these devices, or just putting ReaderBase is enough?
Instead of making whole "ReaderBase" class a friend, can I (and should I) just make the member method "PollforDevice" a friend? Knowing that it's a pure virtual method, would that make inherited copies friends as well?
I'm sorry that the question is a very long one, but I just want to make it clear.
Thanks in advance...
Why bother about constructability of pure abstract base classes like DeviceBase? It can't be constructed anyway if it is a properly designed contract or abstract base class. Unless you have to fit into some kind of framework which you didn't mention, just do the opposite of hiding, e.g.:
struct DeviceBase {
virtual void Foo() = 0;
virtual void Bar() = 0;
virtual ~DeviceBase() = default;
};
By the way, declaring the constructors or destructors private will very effectively make your class "sealed". If for some reason DeviceBase is not abstract (which were a serious design flaw in my eyes) make constructors protected not private. Where you need to bother, is the constructor accessibility of the concrete Device classes. Assuming that you are going to "publish" these implementation classes (i.e. their definitions are accessible to users of your library) and you wish to stress that direct construction is prohibited, use the "access idiom" (my invented name for this):
namespace impl_detail {
class DeviceAccess;
}
class ConcreteDevice1 : public DeviceBase {
friend class impl_detail::DeviceAccess;
// implementation of DeviceBase and all other stuff go
// into the "private" section
};
namespace impl_detail {
class DeviceAccess {
template< class TDevice >
static DeviceBase* Create()
{
return new TDevice;
}
};
};
In your Reader classes use impl_detail::DeviceAccess::Create to construct Device instances, e.g.:
// Your ExternalReader::PollForDevice...
switch (dt) {
case Device1:
return impl_detail::DeviceAccess::Create<ConcreteDevice1>();
case Device2:
// etc...
}
Long story short, best solution is to not publish concrete implementation classes at all, second best some kind of "psychological barrier" which restricts construction, e.g. of the above kind...
Should I explicitly declare in every "Device" that ReaderBase is a friend? Or just declaring at the base "DeviceBase" should be enough?
Should I explicitly put in every "Device" that the "Readers" inherited from the "ReaderBase" are also friends of these devices, or just putting ReaderBase is enough?
As friendship is not inherited (at either side of the friendship relation), the only way your scheme will work is when you declare friendship of every derived Reader in every derived Device. This creates a tight coupling between the Reader classes and the Device classes that is not a nice design.
3) Instead of making whole "ReaderBase" class a friend, can I (and should I) just make the member method "PollforDevice" a friend? Knowing that it's a pure virtual method, would that make inherited copies friends as well?
You could make ReaderX::PollforDevice a friend instead of the entire ReaderX class, but it won't help you much and only opens the door for hard to resolve circular dependencies.
Actually, it is quite hard to create a design where classes of hierarchy X can only be created by classes of hierarchy Y and no one else, without creating a tight coupling between the classes in both hierarchies.
My approach would be
First and foremost, educate your coworkers that if they want a DeviceX, then they can obtain it from a ReaderY and in no other way. Make sure this is enforced in code reviews.
All the other steps are just damage control.
Make sure only the BaseDevice class gets exposed to code outside the Reader's implementation.
Make the destructor of all Device classes protected. This ensures that Device classes can only be cleaned up by derived classes or friends (and automatically rules out stack allocation by non-friends). Should get someone to think twice if they accidentally try to use a Device class directly.
Make the ReaderBase a friend of DeviceBase and give ReaderBase a function to do the actual cleanup of a Device. This is needed to ensure Devices can be cleaned up.
I'm experiencing a challenging problem, which has not been solvable - hopefully until now. I'm developing my own framework and therefore trying to offer the user flexibility with all the code complexity under the hood.
First of all I have an abstract base class which users can implement, obviously simplified:
class IStateTransit
{
public:
bool ConnectionPossible(void) = 0;
}
// A user defines their own class like so
class MyStateTransit : public IStateTransit
{
public:
bool ConnectionPossible(void){ return true; }
}
Next, I define a factory class. Users can register their own custom state transit objects and refer to them later by simply using a string identifier they have chosen:
class TransitFactory : public Singleton<TransitFactory>
{
public:
template<typename T> void RegisterStateTransit(const string& name)
{
// If the transit type is not already registered, add it.
if(transits.find(name) == transits.end())
{
transits.insert(pair<string, IStateTransit*>(name, new T()));
};
}
IStateTransit* TransitFactory::GetStateTransit(const string& type) const
{
return transits.find(type)->second;
};
private:
map<string, IStateTransit*> transits;
}
Now the problem is (probably obviously) that whenever a user requests a transit by calling GetStateTransit the system currently keeps returning the same object - a pointer to the same object that is. I want to change this.
PROBLEM: How can I return a new (clone) of the original IStateTransit object without the user having to define their own copy constructor or virtual constructor. Ideally I would somehow like the GetStateTransit method to be able to cast the IStateTransit object down to the derived type it is at runtime and return a clone of that instance. The biggest hurdle is that I do not want the user to have to implement any extra (and probably complex) methods.
4 hours of Googling and trying has led me nowhere. The one who has the answer is a hero!
The problem is that you don't have the type information to perform the clone as you only have a pointer to base class type and no knowledge as to what derived types have been implemented and are available.
I think there's a reason that 4 hours of googling haven't turned anything up. If you want IStateTransit to be cloneable you have to have an interface where the derived class implementer provides some sort of clone method implementation.
I'm sorry if this isn't what you wanted to hear.
However, implementing a clone method shouldn't be a big burden. Only the class implementor knows how a class can be copied, given a correct copy constructor, clone can be implemented for a leaf-node class like this:
Base* clone() const
{
return new MyType(*this);
}
You could even macro-alize it; although I wouldn't.
If I understand the problem correctly, you shouldn't insert new T -s into the map, but rather objects that create new T-s.
struct ICreateTransit
{
virtual ~ICreateTransit() {}
virtual IStateTransite* create() const = 0;
};
template <class T>
struct CreateTransit: public ICreateTransit
{
virtual IStateTransit* create() const { return new T(); }
};
And now insert:
transits.insert(pair<string, ICreateTransit*>(name, new CreateTransit<T>()));
And retrieve "copies" with:
return transits.find(type)->second->create(); //hopefully with error handling
It shouldn't be impossible to modify StateTransit<T> so it holds a T of which to make copies of, should the default one not do.
I think the general name for techniques like this is called "type erasure" (derived types "remember" particular types, although the base class is unaware of those).
This problem to me sounds that the abstract factory pattern might be of help. Using this pattern the libraries client can define how your framework builds its types. The client can inject his own subclass of the factory into the framework and define there what types should be build.
What you need is (additionaly)
A base class for the factory
As a client: Derive a concrete factory
A way to inject (as a client) a subtype of the factory into the framework
Call the factory metods to create new types.
Does this help you?
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 static method) and put it into a factory class.
Here is a simple factory implementation that forces a factory method on a derived class.
template <class TClass, class TInterface>
class Factory {
public:
static TInterface* Create(){return TClass::CreateInternal();}
};
struct IThingy {
virtual void Method1() = 0;
};
class Thingy :
public Factory<Thingy, IThingy>,
public IThingy {
//Note the private constructor, forces creation through a factory method
Thingy(){}
public:
virtual void Method1(){}
//Actual factory method that performs work.
static Thingy* CreateInternal() {return new Thingy();}
};
Usage:
//Thingy thingy; //error C2248: 'Thingy::Thingy' : cannot access private member declared in class 'Thingy'
IThingy* ithingy = Thingy::Create(); //OK
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:
error C2039: 'CreateInternal' : is not
a member of 'Thingy'
There is no sure way to prescribe such a contract in C++, as there is also no way to use this kind of polymorphism, since the line
Concrete::Factory()
is always a static compile-time thing, that is, you cannot write this line where Concrete would be a yet unknown client-provided class.
You can make clients implement this kind of "contract" by making it more convenient than not providing it. For example, you could use CRTP:
class IThingy {...};
template <class Derived>
class AThingy : public IThingy
{
public:
AThingy() { &Derived::Factory; } // this will fail if there is no Derived::Factory
};
and tell the clients to derived from AThingy<their_class_name> (you could enforce this with constructor visibility tweaking, but you cannot ensure the clients don't lie about their_class_name).
Or you could use the classic solution, create a separate hierarchy of factory classes and ask the clients to provide their ConcreteFactory object to your API.
Static methods cannot be made virtual (or abstract, for that matter) in C++.
To do what you're intending, you can have have an IThingy::factory method that returns a concrete instance, but you need to somehow provide a means for factory to create the instance. For instance, define a method signature like IThing* (thingy_constructor*)() and have a static call in IThingy that you can pass such a function to that defines how IThingy will construct the factory instance. Then, in a dependent library or class, you can call this method with an appropriate function that, in turn, nows how to properly construct an object implementing your interface.
Supposing you haven't had your factory 'initializer' called, you'd want to take appropriate action, such as throwing an exception.