I have a Singleton class with private Ctor, Dtor and one getInstance() method.
class Single {
public:
virtual void* alloc(size_t size, uint line){}
Single* getInstance() {
if(!m_Instance)
m_Instance = __OSAL_NEW OSAL_Memory;
return m_Instance;
}
private:
Single();
~Single();
static Single* m_Instance;
};
#define Allocate(size_t size)\
(Single::getInstance())->alloc(size, __LINE__)
I need to Mock this class using GMOCK.
Is there any way around to mock it.
You could use factory pattern to create your object.
#include <iostream>
#include <functional>
struct A
{
virtual ~A(){}
virtual void foo() = 0;
};
struct Areal : A
{
virtual void foo(){
std::cout<<"real"<<std::endl;
}
};
struct Amock : A
{
virtual void foo(){
std::cout<<"mock"<<std::endl;
}
};
struct Single
{
typedef std::function< A*() > CreatorFn;
static A* getInstance(){
if ( ! instance() )
instance() = (create())();
return instance();
}
static void setCreator( CreatorFn newFn ){
create() = newFn;
}
private:
static CreatorFn& create(){
static CreatorFn f( [](){return new Areal;} );
return f;
}
static A*& instance(){
static A* p=nullptr;
return p;
}
};
bool useMock = true;
int main()
{
if ( useMock )
{
Single::CreatorFn mockFn( [](){ return new Amock; } );
Single::setCreator( mockFn );
}
Single::getInstance()->foo();
}
You just have to make sure that you set the creator before accessing the instance. Otherwise, a default creator function is going to be invoked.
Related
How to remember the template type of a shared_ptr after assigning nullptr?
#include <iostream>
#include <memory>
class Base
{
public:
virtual std::string toString() { return "base"; }
};
class Derived1 : public Base
{
public:
virtual std::string toString() override { return "derived1"; }
};
class Container
{
public:
std::shared_ptr<Base> mMember;
template<class actualType>
void InitializeMember()
{
mMember = std::make_shared<actualType>();
}
void PrintMember()
{
if (mMember)
std::cout << mMember->toString();
}
void RemoveFromMemory()
{
mMember = nullptr;
}
void ReCreateInMemory()
{
// mMember needs to be a shared pointer to a new Derived1 object
}
};
int main()
{
Container container;
// one time initialization
container.InitializeMember<Derived1>();
container.PrintMember();
// ...
container.RemoveFromMemory();
// I need container to allocate a new derived class in mMember
container.ReCreateInMemory();
container.PrintMember();
}
How can I implement ReCreateInMemory(), so that main() prints "derived1" for a second time?
The only time I want to pass the actual type is ONCE in the InitializeMember function.
Thanks.
It will cost you another class member but you can leverage a std::function and a lambda to create a factory function to make objects of the specified type. You can turn your class into
class Container
{
public:
std::shared_ptr<Base> mMember;
template<class actualType>
void InitializeMember()
{
factory = [](){ return std::make_shared<actualType>(); };
mMember = factory();
}
void PrintMember()
{
if (mMember)
std::cout << mMember->toString();
}
void RemoveFromMemory()
{
mMember = nullptr;
}
void ReCreateInMemory()
{
mMember = factory();
}
private:
std::function<std::shared_ptr<Base>()> factory;
};
and now you've stored a way to create the object you create in InitializeMember()
One possibility would be to create a factory function pointer in InitializeMember which you can then call again later to create another object.
class Container
{
public:
std::shared_ptr<Base> mMember;
template<class actualType>
void InitializeMember()
{
mMemberFactory = [](){ return std::make_shared<actualType>(); };
ReCreateInMemory();
}
void PrintMember()
{
if (mMember)
std::cout << mMember->toString();
}
void RemoveFromMemory()
{
mMember = nullptr;
}
void ReCreateInMemory()
{
mMember = mMemberFactory();
}
private:
std::function<std::shared_ptr<Base>()> mMemberFactory;
};
You could also allow passing arguments to the constructor:
template<class actualType, typename ... Args>
void InitializeMember(Args&& ... args)
{
mMemberFactory = [args...](){ return std::make_shared<actualType>(args...); };
ReCreateInMemory();
}
In OgreMain project
OgrePrerequisites.h
#define _OgreExport __declspec( dllexport )
OgreSingleton.h
template<typename T>
class Singleton
{
private:
Singleton(const Singleton<T> &);
Singleton& operator=(const Singleton<T> &);
protected:
static T* msSingleton;
public:
Singleton(void)
{
assert(!msSingleton);
msSingleton = static_cast<T*>(this);
}
~Singleton(void)
{
assert(msSingleton); msSingleton = 0;
}
static T& getSingleton(void)
{
assert(msSingleton); return (*msSingleton);
}
static T* getSingletonPtr(void)
{
return msSingleton;
}
};
OgreRoot.h
class _OgreExport Root : public Singleton<Root>
{
};
Files above are compiled into OgreMain.lib
In RenderSystem_GL project
OgreGLPlugin.cpp
void GLPlugin::install()
{
mRenderSystem = new GLRenderSystem();
Root::getSingleton().addRenderSystem(mRenderSystem);
}
OgreGLPlugin.cpp is compiled into RenderSystem_GL.dll
Ogre share a unique Root object in OgreMain and RenderSystem_GL. How did Ogre make it?
Here is my code.
class DllDemoA in DllDemoA.dll
class __declspec(dllexport) DllDemoA: public Singleton<DllDemoA>
{
public:
DllDemoA()
{
// always assert error
DllDemoB::getSingleton();
}
};
__declspec(dllexport) void Create()
{
DllDemoA* a = new DllDemoA();
}
class DllDemoB in DllDemoB.lib
class __declspec(dllexport) DllDemoB: public Singleton<DllDemoB>
{
};
main.exe link DllDemoB.lib, dynamically load DllDemoA.dll
int main()
{
DllDemoB* b = new DllDemoB();
// no assert error
DllDemoB::getSingleton();
HINSTANCE hMod = LoadLibrary("DllDemoA.dll");
typedef void(*Func)();
Func func = (Func)GetProcAddress(hMod, "Create");
if (func)
{
func();
}
return 0;
}
I would like to implement a Abstract Factory pattern but also would like to be a singleton.
class WindowFactory {
protected:
virtual Scrollbar* createScrollbar() = 0;
};
class MacWindowFactory: public WindowFactory {
virtual Scrollbar* createScrollbar() {
//return a instance
}
;
};
class LinuxWindowFactory: public WindowFactory {
virtual ScrollBar* createScrollbar() {
//return a instance
}
;
};
Can someone help me with some sample code of making this Abstract Factory Singleton ?
Thanks in advance.
I managed to come up with more elegant solution ( No error checking as of now ). Kindly let me know your thoughts
#include<iostream>
#include<map>
class AbstractFactory
{
private:
typedef std::map< std::string, AbstractFactory* > ClientMap;
static ClientMap s_clientMap;
public:
void virtual createScrollbar() = 0;
void virtual createWindow() = 0;
static AbstractFactory* createInstance( std::string client );
protected:
void Register( std::string, AbstractFactory* );
};
AbstractFactory::ClientMap AbstractFactory::s_clientMap;
class LinuxFactory: public AbstractFactory
{
public:
void createScrollbar()
{
std::cout<<"Scrollbar for Linux"<<std::endl;
}
void createWindow()
{
std::cout<<"WIndow for Linux"<<std::endl;
}
private:
LinuxFactory()
{
Register( "Linux", this );
}
LinuxFactory( const LinuxFactory& );
static LinuxFactory s_LinuxFactory;
};
LinuxFactory LinuxFactory::s_LinuxFactory;
class MacFactory: public AbstractFactory
{
public:
void createScrollbar()
{
std::cout<<"Scrollbar for Mac"<<std::endl;
}
void createWindow()
{
std::cout<<"WIndow for Mac"<<std::endl;
}
private:
MacFactory()
{
Register( "Mac", this );
}
MacFactory( const MacFactory& );
static MacFactory s_MacFactory;
};
MacFactory MacFactory::s_MacFactory;
void AbstractFactory::Register( std::string clientName, AbstractFactory* factory )
{
s_clientMap.insert( ClientMap::value_type( clientName, factory ) );
}
AbstractFactory* AbstractFactory::createInstance( std::string client )
{
return s_clientMap.find( client )->second;
}
int main()
{
AbstractFactory *factory = AbstractFactory::createInstance( "Linux" );
factory->createScrollbar();
factory->createWindow();
}
If you need an actually dynamic abstract factory, you'd need to somehow set it up at run-time. You can do this by having a function selecting the desired factory with a suitable function which just sets up the actual singleton. In a real application you would probably have some sort of registration function where you can register functions getting an instance for the factory (factory factory functions). In the example below I used a simple set up where the available factories are known at compile time.
#include <memory>
#include <stdexcept>
#include <string>
class Scrollbar;
class WindowFactory {
public:
static void setFactory(std::string const&);
static Scrollbar* createScrollbar();
virtual ~WindowFactory() {}
private:
virtual Scrollbar* doCreateScrollbar() = 0;
};
class MacWindowFactory
: public WindowFactory {
friend void WindowFactory::setFactory(std::string const&);
virtual Scrollbar* doCreateScrollbar() {
return 0;
}
};
class LinuxWindowFactory
: public WindowFactory {
friend void WindowFactory::setFactory(std::string const&);
virtual Scrollbar* doCreateScrollbar() {
return 0;
}
};
// in WindowFactory.cpp
static std::auto_ptr<WindowFactory>& getPointer()
{
static std::auto_ptr<WindowFactory> pointer;
return pointer;
}
Scrollbar* WindowFactory::createScrollbar()
{
return getPointer().get()
? getPointer()->doCreateScrollbar()
: throw std::runtime_error("WindowFactory not set");
}
void WindowFactory::setFactory(std::string const& what)
{
if (what == "Mac") {
getPointer() = std::auto_ptr<WindowFactory>(new MacWindowFactory());
}
else if (what == "Linux") {
getPointer() = std::auto_ptr<WindowFactory>(new LinuxWindowFactory());
}
else {
throw std::runtime_error("unknown factory: '" + what + "'");
}
}
namespace WindowFactory {
Scrollbar* createScrollbar() {
#ifdef TARGET_OS_MAC
...
#elif __linux__
...
#endif
}
};
It's how I would've done it.
I have an abstract class:
class A
{
public:
bool loaded_;
virtual int load() = 0;
}
And several derived classes :
class B:public A
{
public:
int load();
static B& instance();
}
class C:public A
{
public:
int load();
static C& instance();
}
The fact is that the code inside ::instance() methods is the same for each class :
static B& B::instance()
{
static B instance_;
if (!instance_.loaded_)
{
instance_.load();
instance_.loaded_=true;
}
return instance_;
}
static C& C::instance()
{
static C instance_;
if (!instance_.loaded_)
{
instance_.load();
instance_.loaded_=true;
}
return instance_;
}
I would like to factorize this ::instance method, but given that it uses the virtual method ::load, i cannot define it in the class A.
Theoretically, i know it's weird since the class A should have 0 instance and B,C should have 1 instance but it also makes sense that this code should be factorized.
How would you solve that problem ?
You could make instance() a free function template:
template<class T>
T& instance()
{
static T instance_;
if (!instance_.loaded_)
{
instance_.load();
instance_.loaded_=true;
}
return instance_;
}
Then you can use it like this:
instance<B>().do_stuff()
This is a common usage of the CRTP, define the function that creates the instance in the template and then instantiate it in each type:
struct A {
virtual ~A() {} // don't forget to make your destructor virtual!
virtual void load() = 0;
};
template <typename T>
struct instance_provider {
static T& instance() { /* implementation */ }
};
struct B : A, instance_provider<B> {
virtual void load();
};
struct C : A, instance_provider<C> {
virtual void load();
};
Whats the correct way of implementing this class?
//Header
#include <boost/shared_ptr.hh>
class MyClass
{
public:
static foo()
static foobar();
private:
class pimpl;
static boost::shared_ptr<pimpl> m_handle;
static bool initialized;
};
//source
namespace
{
bool init()
{
//...
// init() can't access m_handle, unless it is a friend of MyClass
// but that seems a bit "tacky", is there a better way?
}
}
class MyClass::pimpl
{
public:
~pimpl(){}
}
bool MyClass::initialized = init();
MyClass::foo()
{
//...
}
MyClass::foobar()
{
//...
}
MyClass is a singleton -- some call it a glorified global. An oft-abused pattern. Use private ctors and a public static accessor:
MyClass {
public:
static MyClass& Instance() {
static MyClass obj;
return obj;
}
// ...
private:
MyClass() : m_handle(pimpl()), initialized(true) {}
// ...
};