How can 2 different classes point to the same datatable name - c++

I need to initialize an object in a method without specifying the class from where the object is. Can I do that?
can someone give me an example?
EDIT:
MyClass{
...};
MySecondClass
{...
};
void method(*object); //how to write correct??
{..}
MyClass *x= new MyClass();
MySecondClass *y= new MySecondClass();
method(x);
method(y);

Use templates.
template <typename T>
void method(T* object) {
// do stuff with the object, whose real type will be substituted for `T`
}
Templates are a bit complex, so read the chapter in your C++ book on them for more information.

It sounds like you're looking for an interface. You would define an interface that fits the needs of whatever it is that your method is doing.
class MyInterface
{
public:
virtual void doSomething1() = 0;
virtual void doSomething2() = 0;
};
class MyObject : public MyInterface
{
public:
void doSomething1()
{
// Code here
}
void doSomething2()
{
// Code here
}
};
It's somewhat unclear exactly the situation you have b/c you haven't shown any code, but make the method you want to call part of a class. (if it isn't already)
class ClassWithMethod
{
public:
ClassWithMethod(MyInterface &myI)
:x(myI)
{
}
void methodYouUseInjectedObject()
{
// Code
x.doSomething1();
// More code
}
private:
MyInterface &x;
};
Then in you application code where you instantiate the ClassWithMethod, you would "inject" the concrete type of the object you want called.
int main(int argc, char *argv[])
{
MyObject myObject;
ClassWithMethod classMethod(myObject);
// Call the method that will use the injected object.
classMethod.methodYouUseInjectedObject();
return 1;
}
EDIT: (based on updated question)
If you want to create a method that can take two different (and unrelated) objects, but the use the same method signatures you can use a template.
class ClassWithMethod
{
public:
template <class T>
void methodYouUseInjectedObject(T object)
{
T.doSomething();
}
};
This is similar to my approach above except that you do not need to derive your different objects off an interface.

You can use a template.
template<typename T>
void method(T object) {
object.doSomething()
}

Related

How to automatically call a method or generate code if a subclass derived from a base class?

I have some classes that describe abilities / behaviours, such as flying, or driving etc. Each of these classes has a specific method that must be called to load some data - For example, Flyable has loadFlyData(), Drivable has loadDriveData(). For each class the method name is unique.
I have many derived classes that may inherit from one or more of these behaviour classes. Each of these derived classes has a method called loadData(), in which we should call all the parent behaviour classes methods such as loadFlyData(), loadDriveData() etc.... Is there a way to automatically generate this method using metaprogramming ? Since there are many derived classes, it may be more maintainable if I can generate these methods using metaprogramming...
Behaviour classes : (An object class may have any of these behaviours, and will have to call that classes "load" method...
class Flyable {
void loadFlyData() {
}
};
class Drivable{
void loadDriveData() {
}
};
All object classes derive from Object:
class Object {
virtual void loadData() {
}
};
A derived class:
class FlyingCar : public Object, public Flyable, public Drivable {
virtual void loadData() override {
// How to automatically generate code so that the next two lines are called:
loadFlyData();
loadDriveData();
}
};
Sure is possible. You'll need however to employ some conventions so the code can be generic. See it live.
#include <iostream>
using namespace std;
struct Flyable{
int loadConcreteData(){
cout << "Flyable\n"; return 0;
}
};
struct Drivable{
int loadConcreteData(){
cout << "Drivable\n"; return 0;
}
};
class Object{
virtual void loadData(){
}
};
template<class ...CS>
struct ConcreteLoader : Object, CS... {
void loadData() override {
int load[] = {
this->CS::loadConcreteData()...
};
}
};
class FlyingCar : public ConcreteLoader<Flyable,Drivable>{
};
int main() {
FlyingCar fc;
fc.loadData();
return 0;
}
Changes that need mentioning:
The return type of each concrete Load function had to be changed. This is to facilitate the "array trick" in expanding the parameter pack.
The names of all the load functions are the same, again for the same reason.
Reason (1) may become obsolete once c++17 and fold expressions roll out.
You can make a free function loadXData() that will become a noop if your class isn't X:
namespace detail
{
void loadFlyData(Flyable* ptr) { ptr->loadFlyData(); }
void loadFlyData(...) {}
void loadDriveData(Drivable* ptr) { ptr->loadDriveData(); }
void loadDriveData(...) {}
}
class FlyingCar : public Object, public Flyable, public Drivable{
public:
virtual void loadData()override{
//How to automatically generate code so that the next two lines are called:
detail::loadFlyData(this);
detail::loadDriveData(this);
}
};
demo
Though I think using a common name loadData and just calling it for all variadic parents might be preferable:
template<typename... Policies>
struct ComposedType : Object, Policies...
{
virtual void loadData() override {
int arr[] = {
((void)Policies::loadData(), 0)...
};
(void)arr;
}
};
using FlyingCar = ComposedType<Drivable, Flyable>;
demo
The above loadData could be simplified in C++1z:
virtual void loadData() override {
((void)Policies::loadData(), ...);
}
demo

Callback via inheritance vs object reference

Compare the following two variants (that should do the same thing)
class Foo
{
public:
void void doStuff()
{
//...
doStuffImpl();
//...
}
virtual void doStuffImpl()=0;
void affectStateInFoo()
{}
};
class Bar:public Foo
{
public:
void doStuffImpl()
{
affectStateInFoo();
}
};
And
class Foo;
class Callback
{
public:
virtual void doStuff(Foo& foo)=0;
};
class Foo
{
public:
Foo(Callback& o):obj(o){}
void void doStuff()
{
//...
obj.doStuff(*this);
//...
}
void affectStateInFoo()
{}
Callback& obj;
};
class Bar:public Callback
{
public:
void doStuff(Foo& foo)
{
foo.affectStateInFoo();
}
};
When is one of the two variants to prefer?
Your first method requires Bar to inherit from Foo, which closely couples these classes. For callbacks this is not always what you want to do. Your second method doesn't require this.
I would use the first method if you actually extending a class, but for notifications I would use the second approach, or as Igor R. mentioned in the comments a function pointer like object.
I would prefer the second one because it is more unit-testable with mocks. But that's just my opinion.
Overdoing stuff per inheritance is a common failure to newcomers of object orientation.
Using delegation, you called it callback, is in common more flexible.
Less numbers of classes
possible reuse of "callback" class
Exchangeable at runtime instead of compiletime

Several C++ classes need to use the same static method with a different implementation

I need several C++ classes to have a static method "register", however the implementation of register varies between those classes.
It should be static because my idea is to "register" all those classes with Lua (only once of course).
Obviously I can't declare an interface with a static pure virtual function. What do you guys suggest me to do ? Simplicity is welcome, but I think some kind of template could work.
Example of what I would like to achieve
class registerInterface
{
public:
static virtual void register() = 0; //obviously illegal
};
class someClass: public registerInterface
{
static virtual void register()
{
//I register myself with Lua
}
}
class someOtherClass: public registerInterface
{
static virtual void register()
{
//I register myself with Lua in a different way
}
}
int main()
{
someClass::register();
someOtherClass::register();
return 0;
}
Based on how you've described the problem, it's unclear to me why you even need the 'virtual static method' on the classes. This should be perfectly legal.
class SomeClass {
static void register(void) {
...
}
}
class SomeOtherClass {
static void register(void) {
...
}
}
int main(int argc, char* argv[]) {
SomeClass::register();
SomeOtherClass::register();
return 0;
}
Drop the RegisterInterface, I don't think you need it.
If it helps, you could take Hitesh's answer, and add:
struct luaRegisterManager {
template <typename T>
void registrate() {
T::registrate();
// do something else to record the fact that we've registered -
// perhaps "registrate" should be returning some object to help with that
}
};
Then:
int main() {
luaRegisterManager lrm;
lrm.registrate<someClass>();
lrm.registrate<someOtherClass>();
}
More generally, if you want to introduce any dynamic polymorphism in C++, then you need an object, not just a class. So again, perhaps the various register functions should be returning objects, with some common interface base class registeredClass, or classRegistrationInfo, or something along those lines.
Could provide an example of what you feel it is that you need dynamic polymorphism for? Hitesh's code precisely matches your one example, as far as I can see, so that example must not cover all of your anticipated use cases. If you write the code that would be using it, perhaps it will become clear to you how to implement it, or perhaps someone can advise.
Something else that might help:
#include <iostream>
#include <string>
#include <vector>
struct Registered {
virtual std::string name() = 0;
virtual ~Registered() {}
Registered() {
all.push_back(this);
}
static std::vector<Registered*> all;
};
std::vector<Registered*> Registered::all;
typedef std::vector<Registered*>::iterator Iter;
template <typename T>
struct RegisteredT : Registered {
std::string n;
RegisteredT(const std::string &name) : n(name) { T::registrate(); }
std::string name() { return n; }
// other functions here could be implemented in terms of calls to static
// functions of T.
};
struct someClass {
static Registered *r;
static void registrate() { std::cout << "registering someClass\n"; }
};
Registered *someClass::r = new RegisteredT<someClass>("someClass");
struct someOtherClass {
static Registered *r;
static void registrate() { std::cout << "registering someOtherClass\n"; }
};
Registered *someOtherClass::r = new RegisteredT<someOtherClass>("someOtherClass");
int main() {
for (Iter it = Registered::all.begin(); it < Registered::all.end(); ++it) {
std::cout << (*it)->name() << "\n";
}
}
There are all sorts of problems with this code if you try to split it across multiple compilation units. Furthermore, this kind of thing leads to spurious reports from memory leak detectors unless you also write some code to tear everything down at the end, or use a vector of shared_ptr, Boost pointer vector, etc. But you see the general idea that a class can "register itself", and that you need an object to make virtual calls.
In C++ you usually try to avoid static initialisation, though, in favour of some sort of setup / dependency injection at the start of your program. So normally you would just list all the classes you care about (calling a function on each one) rather than try to do this automatically.
Your intentions are noble, but your solution is inkling towards "overengineering" (unless I am missing an obvious solution).
Here is one possibility: You can use the Virtual Friend function idiom For example,
class RegisterInterface{
friend void register(RegisterInterface* x){x->do_real_register();}
protected:
virtual void do_real_register();
}
class Foo : public RegisterInterface{
protected:
virtual void do_real_register(){}
};
class Bar : public RegisterInterface{
protected:
virtual void do_real_register(){}
};
int main(int argc, char* argv[]) {
BOOST_FOREACH(RegisterInterface* ri, registered_interfaces)
{
register(ri);
}
return 0;
}
I know you've already accepted an answer, but I figured I would write this up anyway. You can have self-registering classes if you use some static initialization and the CRTP:
#include <vector>
#include <iostream>
using namespace std;
class RegisterableRoot // Holds the list of functions to call, doesn't actually need
// need to be a class, could just be a collection of globals
{
public:
typedef void (*registration_func)();
protected:
static std::vector<registration_func> s_registery;
public:
static void do_registration()
{
for(int i = 0; i < s_registery.size(); ++i)
s_registery[i]();
}
static bool add_func(registration_func func) // returns something so we can use it in
// in an initializer
{
s_registery.push_back(func);
return true;
}
};
template<typename RegisterableType> // Doesn't really need to inherit from
class Registerable : public RegisterableRoot // RegisterableRoot
{
protected:
static const bool s_effect;
};
class A : public Registerable<A> // Honestly, neither does A need to inherit from
// Registerable<T>
{
public:
static void Register()
{
cout << "A" << endl;
}
};
class B : public Registerable<B>
{
public:
static void Register()
{
cout << "B" << endl;
}
};
int main()
{
RegisterableRoot::do_registration();
return 0;
}
std::vector<RegisterableRoot::registration_func> RegisterableRoot::s_registery;
template <typename RegisterableType> // This is the "cute" part, we initialize the
// static s_effect so we build the list "magically"
const bool Registerable<RegisterableType>::s_effect = add_func(&RegisterableType::Register);
template class Registerable<A>; // Explicitly instantiate the template
// causes the equivalent of
// s_registery.push_back(&A::Register) to
// be executed
template class Registerable<B>;
This outputs
A
B
although I wouldn't rely on this order if I were you. Note that the template class Registerable<X> need not be in the same translation unit as the call to do_registration, you can put it with the rest of your definition of Foo. If you inherit from Registerable<> and you don't write a static void Register() function for your class you'll get a (admittedly probably cryptic) compiler error much like you might expect if there really was such a thing as "static virtuals". The "magic" merely adds the class specific function to the list to be called, this avoids several of the pitfalls of doing the actual registration in a static initializer. You still have to call do_registration for anything to happen.
How about this way? Define an interface class:
// IFoobar.h
class IFoobar{
public:
virtual void Register(void) = 0;
}
Then define the class that handles the register..
// RegisterFoobar.h
class RegisterFoobar{
public:
// Constructors etc...
IFoobar* fooBar;
static void RegisterFoobar(IFoobar& fubar){
foobar = &fubar;
}
private:
void Raise(void){ foobar->Register(); }
}
Now, then define another class like this
// MyFuBar.h
class MyFuBar : IFoobar{
public:
// Constructors etc...
void Register(void);
private:
RegisterFoobar* _regFoobar;
}
Call the code like this:
//MyFuBar.cpp
MyFuBar::MyFuBar(){
_regFoobar = new Foobar();
_regFoobar->RegisterFoobar(this);
}
void MyFuBar::Register(void){
// Raised here...
}
Maybe I have misunderstood your requirements...

Enforce static method overloading in child class in C++

I have something like this:
class Base
{
public:
static int Lolz()
{
return 0;
}
};
class Child : public Base
{
public:
int nothing;
};
template <typename T>
int Produce()
{
return T::Lolz();
}
and
Produce<Base>();
Produce<Child>();
both return 0, which is of course correct, but unwanted. Is there anyway to enforce the explicit declaration of the Lolz() method in the second class, or maybe throwing an compile-time error when using Produce<Child>()?
Or is it bad OO design and I should do something completely different?
EDIT:
What I am basically trying to do, is to make something like this work:
Manager manager;
manager.RegisterProducer(&Woot::Produce, "Woot");
manager.RegisterProducer(&Goop::Produce, "Goop");
Object obj = manager.Produce("Woot");
or, more generally, an external abstract factory that doesn't know the types of objects it is producing, so that new types can be added without writing more code.
There are two ways to avoid it. Actually, it depends on what you want to say.
(1) Making Produce() as an interface of Base class.
template <typename T>
int Produce()
{
return T::Lolz();
}
class Base
{
friend int Produce<Base>();
protected:
static int Lolz()
{
return 0;
}
};
class Child : public Base
{
public:
int nothing;
};
int main(void)
{
Produce<Base>(); // Ok.
Produce<Child>(); // error :'Base::Lolz' : cannot access protected member declared in class 'Base'
}
(2) Using template specialization.
template <typename T>
int Produce()
{
return T::Lolz();
}
class Base
{
public:
static int Lolz()
{
return 0;
}
};
class Child : public Base
{
public:
int nothing;
};
template<>
int Produce<Child>()
{
throw std::bad_exception("oops!");
return 0;
}
int main(void)
{
Produce<Base>(); // Ok.
Produce<Child>(); // it will throw an exception!
}
There is no way to override a static method in a subclass, you can only hide it. Nor is there anything analogous to an abstract method that would force a subclass to provide a definition. If you really need different behaviour in different subclasses, then you should make Lolz() an instance method and override it as normal.
I suspect that you are treading close to a design problem here. One of the principals of object-oriented design is the substitution principal. It basically says that if B is a subclass of A, then it must be valid to use a B wherever you could use an A.
C++ doesn't support virtual static functions. Think about what the vtable would have to look like to support that and you'll realize its a no-go.
or maybe throwing a compile-time error when using Produce<Child>()
The modern-day solution for this is to use delete:
class Child : public Base
{
public:
int nothing;
static int Lolz() = delete;
};
It helps avoid a lot of boilerplate and express your intentions clearly.
As far as I understand your question, you want to disable static method from the parent class. You can do something like this in the derived class:
class Child : public Base
{
public:
int nothing;
private:
using Base::Lolz;
};
Now Child::Lolz becomes private.
But, of course, it's much better to fix the design :)

How to design a simple C++ object factory?

In my application, there are 10-20 classes that are instantiated once[*]. Here's an example:
class SomeOtherManager;
class SomeManagerClass {
public:
SomeManagerClass(SomeOtherManager*);
virtual void someMethod1();
virtual void someMethod2();
};
Instances of the classes are contained in one object:
class TheManager {
public:
virtual SomeManagerClass* someManagerClass() const;
virtual SomeOtherManager* someOtherManager() const;
/** More objects... up to 10-20 */
};
Currently TheManager uses the new operator in order to create objects.
My intention is to be able to replace, using plugins, the SomeManagerClass (or any other class) implementation with another one. In order to replace the implementation, 2 steps are needed:
Define a class DerivedSomeManagerClass, which inherits SomeManagerClass [plugin]
Create the new class (DerivedSomeManagerClass) instead of the default (SomeManagerClass) [application]
I guess I need some kind of object factory, but it should be fairly simple since there's always only one type to create (the default implementation or the user implementation).
Any idea about how to design a simple factory like I just described? Consider the fact that there might be more classes in the future, so it should be easy to extend.
[*] I don't care if it happens more than once.
Edit: Please note that there are more than two objects that are contained in TheManager.
Assuming a class (plugin1) which inherits from SomeManagerClass, you need a class hierarchy to build your types:
class factory
{
public:
virtual SomeManagerClass* create() = 0;
};
class plugin1_factory : public factory
{
public:
SomeManagerClass* create() { return new plugin1(); }
};
Then you can assign those factories to a std::map, where they are bound to strings
std::map<string, factory*> factory_map;
...
factory_map["plugin1"] = new plugin1_factory();
Finally your TheManager just needs to know the name of the plugin (as string) and can return an object of type SomeManagerClass with just one line of code:
SomeManagerClass* obj = factory_map[plugin_name]->create();
EDIT: If you don't like to have one plugin factory class for each plugin, you could modify the previous pattern with this:
template <class plugin_type>
class plugin_factory : public factory
{
public:
SomeManagerClass* create() { return new plugin_type(); }
};
factory_map["plugin1"] = new plugin_factory<plugin1>();
I think this is a much better solution. Moreover the 'plugin_factory' class could add itself to the 'factory_map' if you pass costructor the string.
I think there are two separate problems here.
One problem is: how does TheManager name the class that it has to create? It must keep some kind of pointer to "a way to create the class". Possible solutions are:
keeping a separate pointer for each kind of class, with a way to set it, but you already said that you don't like this as it violates the DRY principle
keeping some sort of table where the key is an enum or a string; in this case the setter is a single function with parameters (of course if the key is an enum you can use a vector instead of a map)
The other problem is: what is this "way to create a class"? Unfortunately we can't store pointers to constructors directly, but we can:
create, as others have pointed out, a factory for each class
just add a static "create" function for each class; if they keep a consistent signature, you can just use their pointers to functions
Templates can help in avoiding unnecessary code duplication in both cases.
I have answered in another SO question about C++ factories. Please see there if a flexible factory is of interest. I try to describe an old way from ET++ to use macros which has worked great for me.
ET++ was a project to port old MacApp to C++ and X11. In the effort of it Eric Gamma etc started to think about Design Patterns
I'd create a "base" factory that has virtual methods for creation of all the basic managers, and let the "meta manager" (TheManager in your question) take a pointer to the base factory as a constructor parameter.
I'm assuming that the "factory" can customize the instances of CXYZWManager by deriving from them, but alternatively the constructor of CXYZWManager could take different arguments in the "custom" factory.
A lengthy code example that outputs "CSomeManager" and "CDerivedFromSomeManager":
#include <iostream>
//--------------------------------------------------------------------------------
class CSomeManager
{
public:
virtual const char * ShoutOut() { return "CSomeManager";}
};
//--------------------------------------------------------------------------------
class COtherManager
{
};
//--------------------------------------------------------------------------------
class TheManagerFactory
{
public:
// Non-static, non-const to allow polymorphism-abuse
virtual CSomeManager *CreateSomeManager() { return new CSomeManager(); }
virtual COtherManager *CreateOtherManager() { return new COtherManager(); }
};
//--------------------------------------------------------------------------------
class CDerivedFromSomeManager : public CSomeManager
{
public:
virtual const char * ShoutOut() { return "CDerivedFromSomeManager";}
};
//--------------------------------------------------------------------------------
class TheCustomManagerFactory : public TheManagerFactory
{
public:
virtual CDerivedFromSomeManager *CreateSomeManager() { return new CDerivedFromSomeManager(); }
};
//--------------------------------------------------------------------------------
class CMetaManager
{
public:
CMetaManager(TheManagerFactory *ip_factory)
: mp_some_manager(ip_factory->CreateSomeManager()),
mp_other_manager(ip_factory->CreateOtherManager())
{}
CSomeManager *GetSomeManager() { return mp_some_manager; }
COtherManager *GetOtherManager() { return mp_other_manager; }
private:
CSomeManager *mp_some_manager;
COtherManager *mp_other_manager;
};
//--------------------------------------------------------------------------------
int _tmain(int argc, _TCHAR* argv[])
{
TheManagerFactory standard_factory;
TheCustomManagerFactory custom_factory;
CMetaManager meta_manager_1(&standard_factory);
CMetaManager meta_manager_2(&custom_factory);
std::cout << meta_manager_1.GetSomeManager()->ShoutOut() << "\n";
std::cout << meta_manager_2.GetSomeManager()->ShoutOut() << "\n";
return 0;
}
Here's the solution I thought of, it's not the best one but maybe it will help to think of better solutions:
For each class there would be a creator class:
class SomeManagerClassCreator {
public:
virtual SomeManagerClass* create(SomeOtherManager* someOtherManager) {
return new SomeManagerClass(someOtherManager);
}
};
Then, the creators will be gathered in one class:
class SomeManagerClassCreator;
class SomeOtherManagerCreator;
class TheCreator {
public:
void setSomeManagerClassCreator(SomeManagerClassCreator*);
SomeManagerClassCreator* someManagerClassCreator() const;
void setSomeOtherManagerCreator(SomeOtherManagerCreator*);
SomeOtherManagerCreator* someOtherManagerCreator() const;
private:
SomeManagerClassCreator* m_someManagerClassCreator;
SomeOtherManagerCreator* m_someOtherManagerCreator;
};
And TheManager will be created with TheCreator for internal creation:
class TheManager {
public:
TheManager(TheCreator*);
/* Rest of code from above */
};
The problem with this solution is that it violates DRY - for each class creator I would have to write setter/getter in TheCreator.
This seems like it would be a lot simpler with function templating as opposed to an Abstract Factory pattern
class ManagerFactory
{
public:
template <typename T> static BaseManager * getManager() { return new T();}
};
BaseManager * manager1 = ManagerFactory::template getManager<DerivedManager1>();
If you want to get them via a string, you can create a standard map from strings to function pointers. Here is an implementation that works:
#include <map>
#include <string>
class BaseManager
{
public:
virtual void doSomething() = 0;
};
class DerivedManager1 : public BaseManager
{
public:
virtual void doSomething() {};
};
class DerivedManager2 : public BaseManager
{
public:
virtual void doSomething() {};
};
class ManagerFactory
{
public:
typedef BaseManager * (*GetFunction)();
typedef std::map<std::wstring, GetFunction> ManagerFunctionMap;
private:
static ManagerFunctionMap _managers;
public:
template <typename T> static BaseManager * getManager() { return new T();}
template <typename T> static void registerManager(const std::wstring& name)
{
_managers[name] = ManagerFactory::template getManager<T>;
}
static BaseManager * getManagerByName(const std::wstring& name)
{
if(_managers.count(name))
{
return _managers[name]();
}
return NULL;
}
};
// the static map needs to be initialized outside the class
ManagerFactory::ManagerFunctionMap ManagerFactory::_managers;
int _tmain(int argc, _TCHAR* argv[])
{
// you can get with the templated function
BaseManager * manager1 = ManagerFactory::template getManager<DerivedManager1>();
manager1->doSomething();
// or by registering with a string
ManagerFactory::template registerManager<DerivedManager1>(L"Derived1");
ManagerFactory::template registerManager<DerivedManager2>(L"Derived2");
// and getting them
BaseManager * manager2 = ManagerFactory::getManagerByName(L"Derived2");
manager2->doSomething();
BaseManager * manager3 = ManagerFactory::getManagerByName(L"Derived1");
manager3->doSomething();
return 0;
}
EDIT: In reading the other answers I realized that this is very similar to Dave Van den Eynde's FactorySystem solution, but I'm using a function template pointer instead of instantiating templated factory classes. I think my solution is a little more lightweight. Due to static functions, the only object that gets instantiated is the map itself. If you need the factory to perform other functions (DestroyManager, etc.), I think his solution is more extensible.
You could implement an object factory with static methods that return an instance of a Manager-Class. In the factory you could create a method for the default type of manager and a method for any type of manager which you give an argument representing the type of the Manager-Class (say with an enum). This last method should return an Interface rather than a Class.
Edit: I'll try to give some code, but mind that my C++ times are quite a while back and I'm doing only Java and some scripting for the time being.
class Manager { // aka Interface
public: virtual void someMethod() = 0;
};
class Manager1 : public Manager {
void someMethod() { return null; }
};
class Manager2 : public Manager {
void someMethod() { return null; }
};
enum ManagerTypes {
Manager1, Manager2
};
class ManagerFactory {
public static Manager* createManager(ManagerTypes type) {
Manager* result = null;
switch (type) {
case Manager1:
result = new Manager1();
break;
case Manager2:
result = new Manager2();
break;
default:
// Do whatever error logging you want
break;
}
return result;
}
};
Now you should be able to call the Factory via (if you've been able to make the code sample work):
Manager* manager = ManagerFactory.createManager(ManagerTypes.Manager1);
I would use templates like this as I can't see the point of factories classes:
class SomeOtherManager;
class SomeManagerClass {
public:
SomeManagerClass(SomeOtherManager*);
virtual void someMethod1();
virtual void someMethod2();
};
class TheBaseManager {
public:
//
};
template <class ManagerClassOne, class ManagerClassOther>
class SpecialManager : public TheBaseManager {
public:
virtual ManagerClassOne* someManagerClass() const;
virtual ManagerClassOther* someOtherManager() const;
};
TheBaseManager* ourManager = new SpecialManager<SomeManagerClass,SomeOtherManager>;
You should take a look at the tutorial at
http://downloads.sourceforge.net/papafactory/PapaFactory20080622.pdf?use_mirror=fastbull
It contains a great tutorial on implementing an Abstract factory in C++ and the source code that comes with it is also very robust
Chris
Mh I don't understand a hundred percent, and I am not really into factory stuff from books and articles.
If all your managers share a similar interface you could derive from a base class, and use this base class in your program.
Depending on where the decision which class will be created will be made, you have to use an identifier for creation (as stated above) or handle the decision which manager to instantiate internally.
Another way would be to implement it "policy" like by using templates. So that You ManagerClass::create() returns a specific SomeOtherManagerWhatever instance. This would lay the decision which manager to make in the code which uses your Manager - Maye this is not intended.
Or that way:
template<class MemoryManagment>
class MyAwesomeClass
{
MemoryManagment m_memoryManager;
};
(or something like that)
With this construct you can easily use other managers by only changing the instantiation of MyAwesomeClass.
Also A class for this purpose might be a little over the top. In your case a factory function would do I guess. Well it's more a question of personal preference.
If you plan on supporting plugins that are dynamically linked, your program will need to provide a stable ABI (Application Binary Interface), that means that you cannot use C++ as your main interface as C++ has no standard ABI.
If you want plugins to implement an interface you define yourself, you will have to provide the header file of the interface to plugin programmer and standardize on a very simple C interface in order to create and delete the object.
You cannot provide a dynamic library that will allow you to "new" the plugin class as-is. That is why you need to standardize on a C interface in order to create the object. Using the C++ object is then possible as long as none of your arguments use possibly incompatible types, like STL containers. You will not be able to use a vector returned by another library, because you cannot ensure that their STL implementation is the same as yours.
Manager.h
class Manager
{
public:
virtual void doSomething() = 0;
virtual int doSomethingElse() = 0;
}
extern "C" {
Manager* newManager();
void deleteManager(Manager*);
}
PluginManager.h
#include "Manager.h"
class PluginManager : public Manager
{
public:
PluginManager();
virtual ~PluginManager();
public:
virtual void doSomething();
virtual int doSomethingElse();
}
PluginManager.cpp
#include "PluginManager.h"
Manager* newManager()
{
return new PluginManager();
}
void deleteManager(Manager* pManager)
{
delete pManager;
}
PluginManager::PluginManager()
{
// ...
}
PluginManager::~PluginManager()
{
// ...
}
void PluginManager::doSomething()
{
// ...
}
int PluginManager::doSomethingElse()
{
// ...
}
You didnt talk about TheManager. It looks like you want that to control which class is being used? or maybe you trying to chain them together?
It sounds like you need a abstract base class and a pointer to the currently used class. If you wish to chain you can do it in both abstract class and themanager class. If abstract class, add a member to the next class in chain, if themanager then sort it in order you which to use in a list. You'll need a way to add classes so you'll need an addMe() in themanager. It sounds like you know what your doing so w/e you choose should be right. A list with an addMe func is my recommendation and if you want only 1 active class then a function in TheManager deciding it would be good.
This maybe heavier than you need, but it sounds like you are trying to make a frame work class that supports plugins.
I would break it up into to 3 sections.
1) The FrameWork class would own the plugins.
This class is responsable for publishing interfaces supplied by the plugins.
2) A PlugIn class would own the componets that do the work.
This class is responsable for registering the exported interfaces, and binding the imported interfaces to the components.
3) The third section, the componets are the suppliers and consumers of the interfaces.
To make things extensible, getting things up and running might be broke up into stages.
Create everything.
Wire everything up.
Start everything.
To break things down.
Stop everything.
Destroy everything.
class IFrameWork {
public:
virtual ~IFrameWork() {}
virtual void RegisterInterface( const char*, void* ) = 0;
virtual void* GetInterface( const char* name ) = 0;
};
class IPlugIn {
public:
virtual ~IPlugIn() {}
virtual void BindInterfaces( IFrameWork* frameWork ) {};
virtual void Start() {};
virtual void Stop() {};
};
struct SamplePlugin :public IPlugIn {
ILogger* logger;
Component1 component1;
WebServer webServer;
public:
SamplePlugin( IFrameWork* frameWork )
:logger( (ILogger*)frameWork->GetInterface( "ILogger" ) ), //assumes the 'System' plugin exposes this
component1(),
webServer( component1 )
{
logger->Log( "MyPlugin Ctor()" );
frameWork->RegisterInterface( "ICustomerManager", dynamic_cast( &component1 ) );
frameWork->RegisterInterface( "IVendorManager", dynamic_cast( &component1 ) );
frameWork->RegisterInterface( "IAccountingManager", dynamic_cast( &webServer ) );
}
virtual void BindInterfaces( IFrameWork* frameWork ) {
logger->Log( "MyPlugin BindInterfaces()" );
IProductManager* productManager( static_cast( frameWork->GetInterface( "IProductManager" ) ) );
IShippingManager* shippingManager( static_cast( frameWork->GetInterface( "IShippingManager" ) ) );
component1.BindInterfaces( logger, productManager );
webServer.BindInterfaces( logger, productManager, shippingManager );
}
virtual void Start() {
logger->Log( "MyPlugin Start()" );
webServer.Start();
}
virtual void Stop() {
logger->Log( "MyPlugin Stop()" );
webServer.Stop();
}
};
class FrameWork :public IFrameWork {
vector plugIns;
map interfaces;
public:
virtual void RegisterInterface( const char* name, void* itfc ) {
interfaces[ name ] = itfc;
}
virtual void* GetInterface( const char* name ) {
return interfaces[ name ];
}
FrameWork() {
//Only interfaces in 'SystemPlugin' can be used by all methods of the other plugins
plugIns.push_back( new SystemPlugin( this ) );
plugIns.push_back( new SamplePlugin( this ) );
//add other plugIns here
for_each( plugIns.begin(), plugIns.end(), bind2nd( mem_fun( &IPlugIn::BindInterfaces ), this ) );
for_each( plugIns.begin(), plugIns.end(), mem_fun( &IPlugIn::Start ) );
}
~FrameWork() {
for_each( plugIns.rbegin(), plugIns.rend(), mem_fun( &IPlugIn::Stop ) );
for_each( plugIns.rbegin(), plugIns.rend(), Delete() );
}
};
Here's a minimal factory pattern implementation that I came up with in about 15 minutes. We use a similar one that uses more advanced base classes.
#include "stdafx.h"
#include <map>
#include <string>
class BaseClass
{
public:
virtual ~BaseClass() { }
virtual void Test() = 0;
};
class DerivedClass1 : public BaseClass
{
public:
virtual void Test() { } // You can put a breakpoint here to test.
};
class DerivedClass2 : public BaseClass
{
public:
virtual void Test() { } // You can put a breakpoint here to test.
};
class IFactory
{
public:
virtual BaseClass* CreateNew() const = 0;
};
template <typename T>
class Factory : public IFactory
{
public:
T* CreateNew() const { return new T(); }
};
class FactorySystem
{
private:
typedef std::map<std::wstring, IFactory*> FactoryMap;
FactoryMap m_factories;
public:
~FactorySystem()
{
FactoryMap::const_iterator map_item = m_factories.begin();
for (; map_item != m_factories.end(); ++map_item) delete map_item->second;
m_factories.clear();
}
template <typename T>
void AddFactory(const std::wstring& name)
{
delete m_factories[name]; // Delete previous one, if it exists.
m_factories[name] = new Factory<T>();
}
BaseClass* CreateNew(const std::wstring& name) const
{
FactoryMap::const_iterator found = m_factories.find(name);
if (found != m_factories.end())
return found->second->CreateNew();
else
return NULL; // or throw an exception, depending on how you want to handle it.
}
};
int _tmain(int argc, _TCHAR* argv[])
{
FactorySystem system;
system.AddFactory<DerivedClass1>(L"derived1");
system.AddFactory<DerivedClass2>(L"derived2");
BaseClass* b1 = system.CreateNew(L"derived1");
b1->Test();
delete b1;
BaseClass* b2 = system.CreateNew(L"derived2");
b2->Test();
delete b2;
return 0;
}
Just copy & paste over an initial Win32 console app in VS2005/2008. I like to point out something:
You don't need to create a concrete factory for every class. A template will do that for you.
I like to place the entire factory pattern in its own class, so that you don't need to worry about creating factory objects and deleting them. You simply register your classes, a factory class gets created by the compiler and a factory object gets created by the pattern. At the end of its lifetime, all factories are cleanly destroyed. I like this form of encapsulation, as there is no confusion over who governs the lifetime of the factories.