Reputation: 2495
I'm working on simple framework written on C++. Now i have something like
app.cpp
#include "app.h"
namespace App
{
}
void App::init()
{
}
void App::timerEvent(int time)
{
}
But what if i don't want to listen to timerEvent in some cases? I still have to write empty method implementation.
My idea is to move from namespace to class App : public BaseApp
with virtual void BaseApp::init() = 0
and virtual void BaseApp::timerEvent(int time) {}
in BaseApp
(similary to Qt QApplication
). However App should be singleton then, but i don't see any way to specify it from BaseApp
, so i have to write singleton code in App
and all virtual idea makes no sense.
How should i design it?
P.S. I don't want to use listeners here. It seems like overkill for me.
P.P.S. I need singleton because i initialize app instance from main
, but still want to access its methods from another classes.
Upvotes: 3
Views: 1969
Reputation: 2972
You can emulate virtual functions inside your namespace with function pointer or std::function. Just make something like this:
#include "app.h"
namespace App
{
std::function<void(int)> vtTimerEvent;
}
void App::timerEventImpl(int time)
{
// default timerEvent implementation
}
void App::init(std::function<void(int)> timerEvent = &App::timerEventImpl)
{
vtTimerEvent = timerEvent;
}
void App::timerEvent(int time)
{
vtTimerEvent(time);
}
This is not very great design, but it does what you want.
UPDATE
Another approximation:
#include <memory>
#include <stdexcept>
// virtual base interface
class IInterface
{
public:
virtual ~IInterface() = 0;
};
IInterface::~IInterface(){} // must have
// virtual App interface
class IApp :
virtual public IInterface
{
public:
virtual void init() = 0;
virtual void timerEvent(int time) = 0;
};
// static App interface
class App
{
private:
~App(); // nobody can create an instance
public:
static void init(const std::shared_ptr<IApp> &impl_p)
{
if (!impl)
{
impl = impl_p;
impl->init();
}
else
{
throw std::runtime_error("Already initialized");
}
}
static void timerEvent(int time)
{
impl->timerEvent(time);
}
private:
static std::shared_ptr<IApp> impl;
};
std::shared_ptr<IApp> App::impl;
// specific App implementation
class AppImplementation1 :
public IApp
{
//...
};
int main(int, char**)
{
auto myImpl = std::make_shared<AppImplementation1>();
App::init(myImpl);
//...
return 0;
}
Upvotes: 2