使用虚拟方法组织单例的最佳方式



我正在研究用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,并在BaseAppvirtual 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;
}

最新更新