How using dependency injection in a shared library (dll, so)? - c++

Let's say in C++ I have an API in a shared library and I want to inject some dependence in it, at initialization. How can I do that ?
For example, in the calling code :
#include "CTest1.h"
#include "CTest2.h"
...
#include "CTest15.h"
class CTest{
int att1;
int att2;
}
and in the shared library :
#include "CTest.h"
class export CSharedObject{
void create(CTest* test){ mtest = test; }
void doSomething(){ int sum = test->att1+test->att2; }
CTest* mtest;
}
How can I inject CTest in CSharedObject ? Just with the include ? But CSharedObject will need all the files CTest needs
I need to avoid all these includes

First, your class needs an interface :
class CTestIface
{
virtual ~CTestIface(){}
virtual void foo() = 0;
};
Then in the library add an implementation :
class CTest1 : public CTestIface
{
void foo(){ /*...*/ }
};
and c functions to create/delete objects of type CTest11:
extern C{
void* Create() { return new CTest1; };
void Delete( void* o ) { delete( (CTest1*) o ); }
}
As you can see, you just need a header defining the interface, and functions to create/delete objects.
by the way, in tests, you should use mock classes (inheriting from the interface)

Related

Overloading of functions in C++ code when using extern "C"

I want to load libraries at run time. I have a base class "Base" and two derived classes "Derived1" and "Derived2" which should be loaded at runtime. I am using the approach from this answer with some small modifications. The code compiles perfectly when I define only one derived class, but it fails to compile when several derived classes are defined. The compilation error is the following:
multiple definitions of 'create'
I think that the problem is "C" doesn't allow overloading of function names. How would one solve this problem?
The important point is that since I don't know how many .so files exist, I want to have one handler for all .so files. The details of the code are given below:
base.hpp:
class Base {
public:
virtual ~Base() {}
virtual void foo() const = 0;
};
using Base_creator_t = Base *(*)();
derived1.hpp:
#include "Interface.hpp"
class Derived1: public Base {
public:
void foo() const override {}
};
extern "C" {
Base * create() {
return new Derived1;
}
}
derived2.hpp:
#include "Interface.hpp"
class Derived2: public Base {
public:
void foo() const override {}
};
extern "C" {
Base * create() {
return new Derived2;
}
}
Dynamic shared library handler: Derived_factory.hpp:
#include <dlfcn.h>
class Derived_factory {
public:
Derived_factory(char* path) {
handler = dlopen(path, RTLD_NOW);
if (! handler) {
throw std::runtime_error(dlerror());
}
Reset_dlerror();
creator = reinterpret_cast<Base_creator_t>(dlsym(handler, "create"));
Check_dlerror();
}
std::unique_ptr<Base> create() const {
return std::unique_ptr<Base>(creator());
}
~Derived_factory() {
if (handler) {
dlclose(handler);
}
}
private:
void * handler = nullptr;
Base_creator_t creator = nullptr;
static void Reset_dlerror() {
dlerror();
}
static void Check_dlerror() {
const char * dlsym_error = dlerror();
if (dlsym_error) {
throw std::runtime_error(dlsym_error);
}
}
};
main.cpp:
#include "Derived_factory.hpp"
int main(){
Derived_factory factoryOne("Derived1.so");
std::unique_ptr<Base> baseOne = factoryOne.create();
baseOne->foo();
Derived_factory factoryTwo("Derived2.so");
std::unique_ptr<Base> baseTwo = factoryTwo.create();
baseTwo->foo();
return 0;
}
The problem is not extern "C". The problem is you have multiple definitions of the same function.
Base * create() is indistinguishable from Base * create()
What you're trying to do is to have the same function in two different loadable modules. But what you're doing instead is putting both implementations (with the same name and signature!) of this function into the main module, which of course results in multiple definition error.
What you should do instead is put the create functions into the *.cpp files, i.e. derived1.cpp and derived2.cpp, omit their definitions from the *.hpp files, and compile the shared objects from these *.cpp files. I've modified your project to achieve this, see the live demo.

How to test classes that is derived from external base class which depends on external system

I have a class that is subclass of an external class over which I don't have any control. The external class depend on system resources. For example
class MyClass : public ExternalBase // This class is from external framework and framework requires it to derive from this class.
{
int doSomePrivateThing(int );
public:
virtual int DoSomething(int );
virtual ~MyClass();
}
int MyClass::doSomePrivateThing(int )
{
// do some private task
}
int MyClass::DoSomething(int n)
{
// Do MyClass Specific task
int k = doSomePrivateThing(n);
return ExternalBase::DoSomething(k); // This function depends on external system resources.
// Probably try to communicate with remote server
// or attempt access Storage or Display device etc.
}
MyClass::~MyClass()
{}
How can I break the dependency of MyClass and write unit test for MyClass::DoSomething(). Using composition in place of inheritance is not a choice as framework requires classes to be derived from this base class.
I am using C++ and GoogleTest/Mock. But any generalized solution is appreciated.
Thanks in advance.
There are two ways. I call them "a little more correct" way and "very ugly" way.
The "more correct" way:
Enclose external class functions with some additional layer than can be partial mocked.
class MyClass : public ExternalBase // This class is from external framework and framework requires it to derive from this class.
{
int doSomePrivateThing(int );
public:
virtual void BaseDoSomething(int) { return ExternalBase::DoSomething(v); }
virtual int DoSomething(int v);
virtual ~MyClass();
};
int MyClass::DoSomething(int n)
{
// Do MyClass Specific task
int k = doSomePrivateThing(n);
return BaseDoSomething(k);
}
And partial mock in UT in this way:
class TestableMyClass : public MyClass
{
public:
using MyClass::MyClass;
MOCK_METHOD1(BaseDoSomething, int(int));
};
TEST(A,A)
{
TestableMyClass objectUnderTest;
EXPECT_CALL(objectUnderTest, BaseDoSomething(112));
objectUnderTest.DoSomething(112);
}
When you need to call also the true base class method in your test - use WillOnce(Invoke...) with EXPECT_CALL.
The "very ugly" way:
Provide your own UnitTest implementation of ExternalBase and link it to your test. This "UnitTest" impolementation of ExternalBase should be based on some global Mocks objects.
ExternalBaseMock.hpp:
class ExternalBaseMock
{
public:
MOCK_METHOD1(DoSomething, int(int));
};
extern ExternalBaseMock externalBaseMock;
ExternalBaseMock.cpp:
ExternalBaseMock externalBaseMock;
int ExternalBase::DoSomething(int n)
{
return externalBaseMock.DoSomething(n);
}
Then your tests:
#include "ExternalBaseMock.hpp"
TEST(A,A)
{
MyClass objectUnderTest;
EXPECT_CALL(externalBaseMock, DoSomething(112));
objectUnderTest.DoSomething(112);
}

How to mock malloc to return null in GMOCK?

I want to mock malloc in C++ using Gmock framework. Is it possible? I have tried all possible ways. But the class which is hosting this malloc implementation has got a private constructor and destructor?
Is there any way in which we can directly mock malloc to return NULL?
DeveloperLove,
first of all mocking of standard library is never a good practice and testing the code on such granulation level is art for art's sake. You have to notice that from very beginning, tests become the part of the project and if you want to keep them up-to-date (aka maintaing working regression) you have to think about their design in the same way as production code. In fact tests are also the code which has to be maintained during lifetime of project and if reading, correcting and finnaly understading that tests will take too much time, such regression will be useless. Try to think about it as the "life documentation".
Nevertheless, probably one of the ugliest way to mock the standard C library is static hook and macros. Consider the following example:
#include <gtest/gtest.h>
#include <gmock/gmock.h>
#include <boost/bind.hpp>
#include <boost/function.hpp>
static boost::function<void*(size_t)> malloc_bridge;
struct StdlibMock
{
StdlibMock()
{
malloc_bridge = boost::bind(&StdlibMock::mallocMock, this, _1);
}
MOCK_METHOD1(mallocMock, void*(size_t));
}; // struct Struct StdlibMock
void* malloc_cheat(size_t size)
{
return malloc_bridge(size);
}
#define malloc malloc_cheat
struct Sut
{
void f()
{
malloc(10);
}
};
struct TestWithMalloc : ::testing::Test
{
StdlibMock stdlibMock;
}; // struct TestWithMalloc
TEST_F(TestWithMalloc, ShouldMalloc10Bytes)
{
EXPECT_CALL(stdlibMock, mallocMock(10))
.WillOnce(::testing::Return(static_cast<void*>(0)));
Sut sut;
sut.f();
}
#undef malloc
Notice that you cannot replace the mallocMock function name with simple malloc because of using of preprocessor macro.
Hopefully, was a little bit helpful.
Wrap malloc
Pass the wrapper to the tested class c'tor in production code
Mock the wrapper (can also create interface above the wrapper and mock it)
Pass the mock to the tested class c'tor in test code
class I_mallocWrapper
{
public:
virtual ~I_mallocWrapper() {}
virtual void* myMalloc (size_t size) = 0;
};
//wrapper to malloc
class mallocWrapper : public I_mallocWrapper
{
public:
virtual void* myMalloc (size_t size) {return malloc(size);}
virtual ~mallocWrapper() {}
mallocWrapper(){}
};
//tested class with tested method that uses the wrapper
class TestedClass
{
public:
TestedClass(I_mallocWrapper* mallocW) { this->m_mallocWrapper = mallocW; }
void testedMethod(size_t size) { m_mallocWrapper->myMalloc(size); }
virtual ~TestedClass() {}
private:
I_mallocWrapper* m_mallocWrapper;
};
//production code
void main()
{
size_t size = 18;
I_mallocWrapper* MW = new mallocWrapper;
TestedClass* TC = new TestedClass(MW);
TC->testedMethod(size);
}
//mock the wrapper
class mockMallocWrapper : public I_mallocWrapper
{
public:
MOCK_METHOD1(myMalloc, void*(size_t size));
};
//test code
TEST(MallocTest,callMalloc)
{
size_t size = 18;
I_mallocWrapper* MW = new mockMallocWrapper;
TestedClass* TC = new TestedClass(MW);
TC->testedMethod(size);
EXPECT_CALL(MW, myMalloc(_))
.WillOnce(Return(NULL))
}
glibcmock can help you mock malloc and other libc function.
#include "got_hook.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include <mutex>
#include <memory>
struct MockMalloc {
MOCK_METHOD1(Malloc, void *(size_t));
};
static MockMalloc *g_mock{nullptr};
static void *Malloc(size_t size) {
return g_mock->Malloc(size);
}
static std::mutex g_test_mutex;
TEST(MallocTest, ReturnNull) {
std::lock_guard<std::mutex> lock(g_test_mutex);
std::unique_ptr<MockMalloc> mock(g_mock = new MockMalloc());
testing::GotHook got_hook;
ASSERT_NO_FATAL_FAILURE(got_hook.MockFunction("malloc", (void*)&Malloc););
// ... do your test here, for example:
EXPECT_CALL(*g_mock, Malloc(testing::_)).WillOnce(testing::Return(nullptr));
EXPECT_EQ(nullptr, malloc(1));
}

Inheritance in C++

EDIT 2:
Here is a simple summary of what I want to do (I think):
I want to dynamically create global instances based on conditions that are calculated at run time.
You can skip to EDIT1 if you'd like to take a look at sample code, but at this point, the above bolded-text is probably the easiest to understand...
END EDIT 2.
My question is about polymorphism and inheritance. Specifically, I want to know if there is a way I could inherit functions and pointers from another class.
I have a class called Globals which contains various pointers to objects to other classes as well as various functions. Instead of copy/pasting code, I'll write up a simple example:
(I've removed header guards for simplicity and cleanliness)
The following is my globals.h and globals.cpp, respectively:
// Example of globals.h
#include <iostream>
#include <cstdio>
using namespace std;
class Globals {
public:
Globals ();
virtual ~Globals ();
void function1(char*);
void function2();
class Input *input;
class Error *error;
};
// Example of globals.cpp
#include "globals.h"
Globals::Globals()
{
input = new Input();
error = new Error();
}
void Globals::function1(char*nm)
{
cout << nm << endl;
}
Now, in my code for my Input class, say I want to use the function1(char*) method, would this be possible without passing an object to the Input class? What I mean by this is that I currently have my Input class being passed a *globals object, so then I could call the function like so: globals->function2();. But this can get very messy if I have a lot of functions within different classes. Additionally, is there a way I could use the Error pointer to object initialized in Globals? If Error had a function called error_func(), how could I be able to call it like so: error->error_func() from within my Input functions?
Thanks, and I apologize if I were too confusing in my question. I'll be happy to elaborate if needed.
Amit
EDIT 1: Added a simplified code to present what I want to do in a clearer way
// Example of globals.h
#include <iostream>
#include <cstdio>
#include "input.h"
#include "error.h"
using namespace std;
class Globals {
public:
Globals ();
virtual ~Globals ();
class Input *input;
class Error *error;
};
// Example of globals.cpp
#include "globals.h"
Globals::Globals()
{
input = new Input();
error = new Error();
}
// Example of input.h
#include "globals.h"
class Input {
public:
Input();
virtual ~Input();
}
// Example of input.cpp
#include "globals.h"
Input::Input()
{
error->print("Hello\n"); // <-- THIS is really what I want to accomplish (without being sent a globals object and say globals->error->print();
}
// Example of error.h
#include "globals.h"
class Error {
public:
Error() { }
virtual ~Error() { }
void print(char*);
}
// Example of error.cpp
#include "globals.h"
Error::print(char* nm)
{
cout << nm << endl;
}
If I'm understanding your question right, functions are automatically "inherited", at least for the purposes you need.
For example, your global class has two methods, function1(char*) and function2(). If you make a class:
class Descendent
: public Global
{ };
int main()
{
Global * global = new Global();
Global * desc = new Descendant();
char * str = "string";
// These two will run the same function:
global->function1(str);
desc->function1(str);
}
To prevent that (functions being called based on the current type), you must use virtual, like:
class Global
{
virtual void function1(char *);
};
class Descendant
{
virtual void function1(char *);
};
int main()
{
Global * global = new Global();
Global * desc = new Descendant();
char * str = "string";
// These two will NOT run the same function:
global->function1(str);
desc->function1(str);
}
Now, I'm not entirely sure, but the singleton idiom may be of use here, depending on just how global your Global is. In that case, you would have a global like:
class Global
{
static Global * GetSingleton()
{
if (!Global::m_Instance) Global::m_Instance = new Global();
return Global::m_Instance;
}
void function1(char *);
static Global * m_Instance;
};
class Descendant
{
void function1(char *)
{
Global * global = Global::GetGetSingleton();
// ...
}
};
There are a variety of ways to work with globals and functions being needed between classes. One of these may be it, depending on what exactly you're doing. If not, I'll try to edit and suggest one that does work.
I'm imagining you have a situation like this:
struct A {
void f();
};
struct B {
void g();
};
struct C : virtual A, virtual B {
C(A *ap, B *bp)
: A(ap), B(bp) // This doesn't actually work -- theoretical
{
}
void h()
{
f(); // calls A::f()
g(); // calls B::g();
}
};
Normally, when you create a C, you would be creating new As and Bs, but you would like to re-use existing ones instead, but still treat it like inheritance so that you don't have to explicitly specify which object to call.
Unfortunately, C++ doesn't support this. There are a couple of options:
You can make proxy classes that defer the function calls:
struct AProxy {
AProxy(A *ap) : a(*ap) { }
void f() { a.f(); }
A &a;
};
struct BProxy {
BProxy(B *bp) : b(*bp) { }
void g() { b.g(); }
B &b;
};
struct C : AProxy, BProxy {
C(A *ap,B *bp) : AProxy(ap), BProxy(bp) { }
void h()
{
f(); // calls AProxy::f() which calls a.f()
g(); // calls BProxy::g() which calls b.g()
}
};
This may help if you are using A's and B's in lots of different places.
If instead, you don't have many classes, but lots of calls to f() and g(), you might just do this:
struct C {
C(A *ap,B *bp) : a(*ap), b(*bp) { }
void f() { a.f(); }
void g() { b.g(); }
void h1()
{
f(); // well at least the call is clean here
g();
}
void h2()
{
f(); // and clean here
g();
}
A &a;
B &b;
};
If you don't have either of these cases, then just using the proper object each time like you were doing may be best.
Updated response:
Its sounds like what you want is actually the Factory pattern. I'm going to use logging as an example, where I assume that in one configuration you want to log and in another you might not want to:
// logger_interface.h
class LoggerInterface {
public:
virtual ~LoggerInterface() {}
virtual void Log(const string& message) = 0;
protected:
LoggerInterface() {}
};
The first step is to create a pure virtual interface representing the behavior that is configurable as in the example above. We will then create a factory function that can construct one based on configuration:
// logger_factory.h
LoggerInterface* CreateLogger(LoggerOptions options);
When implementing the factory, we keep the different implementations hidden:
// logger_factory.cc
class DoNotLogLogger : public LoggerInterface {
public:
DoNotLogLogger() {}
virtual ~DoNotLogLogger() {}
virtual void Log(const string& message) {}
};
class LogToStdErrLogger : public LoggerInterface {
public:
LogToStdErrLogger() {}
virtual ~LogToStdErrLogger() {}
virtual void Log(const string& message) {
std::cout << message << std::endl;
}
};
LoggerInterface* CreateLogger(LoggerOptions options) {
if (options.IsLoggingEnabled() && options.ShouldLogToStdErr()) {
return new LogToStdErrLogger;
}
return new DoNotLogLogger;
}
There is no reason why the object that you create dynamically in this way needs to be global; in fact, making it global is a really bad idea. Just create it where you need it, and pass it as a parameter to the functions that need it.
Original response:
Inheritance isn't the word you are looking for. Basically, what you are asking for is a static function:
class ClassName {
public:
static void methodName();
};
In the above, methodName can be invoked using ClassName::methodName() without requiring a specific instance of the class named ClassName. However, if you are to do this, it is more consistent with C++ style conventions to make it a freestanding function in a namespace like:
namespace name_of_namespace {
void functionName();
}
The above is invoked using name_of_namespace::functionName() as in the previous example, except with the benefit that it is easier to change or remove the prefix (e.g. via a using directive).
NOTE: from a design standpoint, you should only use a freestanding or static function if it does not rely on any state (other than the parameters passed to it) and there is no possibility of alternative implementations. As soon as there is state or alternative implementations, you really should pass around an object encapsulating this state, even if it is a pain to do, since passing around the object makes it easier to configure, makes it easier to mock-out in tests, and avoids threading issues.

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.