我正在研究用C++编写的简单框架。现在我有类似的东西
应用.cpp
#include "app.h"
namespace App
{
}
void App::init()
{
}
void App::timerEvent(int time)
{
}
但是,如果我在某些情况下不想收听 timerEvent 怎么办?我仍然必须编写空的方法实现。
我的想法是用virtual void BaseApp::init() = 0
从命名空间移动到class App : public BaseApp
,并在BaseApp
中virtual void BaseApp::timerEvent(int time) {}
(类似于Qt QApplication
)。但是 App 应该是单例的,但我看不到任何方法可以从BaseApp
中指定它,所以我必须在App
中编写单例代码,所有虚拟想法都没有意义。
我应该如何设计它?
附言我不想在这里使用侦听器。这对我来说似乎有点矫枉过正。
附言我需要单例,因为我从main
初始化应用程序实例,但仍想从另一个类访问其方法。
您可以使用函数指针或 std::function 模拟命名空间内的虚拟函数。只需制作这样的东西:
#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);
}
这不是很好的设计,但它可以满足您的要求。
更新
另一个近似值:
#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;
}