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)
Related
In below code I have abstract class TestAlgModule which I will be exposing to library users and there are several functionalities they can use such as VOLUME, MIXER and so on. However, suppose users need a new function which is added only in MixerManager then I need to add that in TestAlgModule abstract class and now suddenly all the derived class needs to add that without any benefit.
How do I avoid this?
#include <iostream>
using namespace std;
enum {VOLUME, MIXER, UNKNONWN};
class TestAlgModule {
public:
virtual void open(int type) = 0;
virtual void close(int type) = 0;
};
class volumeManager : public TestAlgModule
{
public:
void open(int type) {}
void close(int type) {}
};
class mixerManager : public TestAlgModule
{
public:
void open(int type) {}
void close(int type) {}
void differentFunction() {};
};
/* users calls this to get algModule and then call functions to get the job done */
TestAlgModule *getTestAlgModule(int type) {
switch(type) {
case VOLUME:
return new volumeManager();
case MIXER:
return new mixerManager();
default:
break;
}
return nullptr;
}
int main() {
TestAlgModule * test = getTestAlgModule(MIXER);
test->open();
//test->differentFunction(); this can't be called as it is not part of abstract class and users are exposed only abstract class
return 0;
}
If something is not clear please let me know and I will do my best to answer it. I am looking for a better way to do this i.e. change in VolumeManager should be independent of MixerManager.
If you want to use an abstract factory, like you did in above code, then you need to return a pointer to the base class. That is correct. And then you need to invoke all functions through the base pointer.
By the way, please do not use raw pointers. Please use std::unique pointers instead.
There are 2 possible solutions.
Add the interface functions as a none pure, but still virtual function to your base class, with a default behaviour.
virtual void differentFunction() {}
Because of the other pure functions, the base class is still abstract. This may lead to a fat interface. But in many cases it is an acceptable solution.
The second possibility is to downcast the base class pointer to your needed pointer, using dynamic_cast and checking the return value of the dynamic cast.
if(mixerManager* mm = dynamic_cast<mixerManager*>(test)) {
mm->differentFunction();
}
All this depends of course on the overall design and what you want to achieve. But the above 2 are the standard patterns.
There are also other design patterns that may fit your needs, like builder or prototype. Please check.
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...
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 am upgrading an old application which was written for a specific hardware interface. I now need to add support for a modern hardware to the existing application.
To do this, I would like to create a class for each hardware type, and assign a variable to one type or the other whenever the user selects which hardware is in their system.
For example:
Class HardwareType1 and Class HardwareType2 both exist having the same member functions.
object HW;
if (userHwType = 1)
// initialize HW as a HardwareType1 class
}
else{
// initialize HW as a HardwareType2 class
}
Now I can use HW.doSomething() throughout my code without a conditional for hardware type every time I interact with the hardware.
I'm sure this is pretty basic but to be honest I don't even know what this is called or what terms to search on for this one.
Thanks!
Create an an abstract base class, and derive two concrete classes from it: one implementing type1 and the other implementing type2:
class Hardware
{
public:
virtual ~Hardware() {};
virtual void doSomething() = 0;
};
class Hardware1: public Hardware
{
public:
void doSomething() { // hardware type1 stuff. }
};
class Hardware2: public Hardware
{
public:
void doSomething() { // hardware type2 stuff. }
};
Then create the necessary instance:
std::unique_ptr<Hardware> hardware(1 == userHwType ? new Hardware1() :
new Hardware2());
hardware->doSomething();
If you compiler does not support C++11 then std::unique_ptr will not be available to you. An alternative smart pointer would boost::scoped_ptr (or boost::shared_ptr).
Use polymorphism with a common abstract base class, like this:
class HardwareBase
{
public:
virtual void Open() = 0;
virtual void Close() = 0;
virtual ~HardwareBase() {};
};
Then derive your concrete hardware types:
class HardwareType1 : public HardwareBase
{
public:
virtual void Open() {...}
virtual void Close() {...}
};
And select the required hardware instance:
std::unique_ptr<HardwareBase> hw;
if (userHwType == 1)
hw.reset(new HardwareType1());
else
hw.reset(new HardwareType2());
// And use it like this:
hw->Open();
Note that you now need a pointer to the selected object instance.
Use a unique_ptr to automatically delete it on exit.
The term to search for is polymorphism; that's the general term for interacting with different types through a common interface.
In C++, if you need to select behaviour at runtime, the usual approach is to define an abstract interface, which acts as a base class for your concrete types, using virtual functions - the function to call is chosen at runtime depending on the true type of the object.
// Abstract interface
class Hardware {
public:
virtual ~Hardware() {} // needed to safely delete objects
virtual void doSomething() = 0; // must be implemented by each concrete type
};
// One concrete type
class HardwareType1 : public Hardware
{
HardwareType1() { /* initialise */ }
void doSomething() { /* implementation for this type of hardware */ }
};
// Another concrete type
class HardwareType2 : public Hardware
{
HardwareType2() { /* initialise */ }
void doSomething() { /* implementation for this type of hardware */ }
};
Now you can choose which to create, and then interact using the abstract interface:
// Create the correct type, depending on user input
std::unique_ptr<Hardware> hw
((userHwType == 1) ? new HardwareType1 : new HardwareType2);
// Do the right thing depending on the type
hw->doSomething();
You could search for factory method. That is the name of the pattern you are trying to implement
I'm developing a GUI library with a friend and we faced the problem of how to determine whether a certain element should be clickable or not (Or movable, or etc.).
We decided to just check if a function exists for a specific object, all gui elements are stored in a vector with pointers to the base class.
So for example if I have
class Base {};
class Derived : public Base
{
void example() {}
}
vector<Base*> objects;
How would I check if a member of objects has a function named example.
If this isn't possible than what would be a different way to implement optional behaviour like clicking and alike.
You could just have a virtual IsClickable() method in your base class:
class Widget {
public:
virtual bool IsClickable(void) { return false; }
};
class ClickableWidget : public Widget
{
public:
virtual bool IsClickable(void) { return true; }
}
class SometimesClickableWidget : public Widget
{
public:
virtual bool IsClickable(void);
// More complex logic punted to .cc file.
}
vector<Base*> objects;
This way, objects default to not being clickable. A clickable object either overrides IsClickable() or subclasses ClickableWidget instead of Widget. No fancy metaprogramming needed.
EDIT: To determine if something is clickable:
if(object->IsClickable()) {
// Hey, it's clickable!
}
The best way to do this is to use mixin multiple inheritance, a.k.a. interfaces.
class HasExample // note no superclass here!
{
virtual void example() = 0;
};
class Derived : public Base, public HasExample
{
void example()
{
printf("example!\n");
}
}
vector<Base*> objects;
objects.push_back(new Derived());
Base* p = objects[0];
HasExample* he = dynamic_cast<HasExample*>(p);
if (he)
he->example();
dynamic_class<>() does a test at runtime whether a given object implements HasExample, and returns either a HasExample* or NULL. However, if you find yourself using HasExample* it's usually a sign you need to rethink your design.
Beware! When using multiple inheritance like this, then (HasExample*)ptr != ptr. Casting a pointer to one of its parents might cause the value of the pointer to change. This is perfectly normal, and inside the method this will be what you expect, but it can cause problems if you're not aware of it.
Edit: Added example of dynamic_cast<>(), because the syntax is weird.
If you're willing to use RTTI . . .
Instead of checking class names, you should create Clickable, Movable, etc classes. Then you can use a dynamic_cast to see if the various elements implement the interface that you are interested in.
IBM has a brief example program illustrating dynamic_cast here.
I would create an interface, make the method(s) part of the interface, and then implement that Interface on any class that should have the functionality.
That would make the most sense when trying to determine if an Object implements some set of functionality (rather than checking for the method name):
class IMoveable
{
public:
virtual ~IMoveable() {}
virtual void Move() = 0;
};
class Base {};
class Derived : public Base, public IMoveable
{
public:
virtual void Move()
{
// Implementation
}
}
Now you're no longer checking for method names, but casting to the IMoveable type and calling Move().
I'm not sure it is easy or good to do this by reflection. I think a better way would be to have an interface (somethign like GUIElement) that has a isClickable function. Make your elements implement the interface, and then the ones that are clickable will return true in their implementation of the function. All others will of course return false. When you want to know if something's clickable, just call it's isClickable function. This way you can at runtime change elements from being clickable to non-clickable - if that makes sense in your context.