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

时间:2016-03-12 12:06:12

标签: c++ design-patterns

我正在研究用C ++编写的简单框架。现在我有类似

的东西

app.cpp

#include "app.h"

namespace App
{

}

void App::init()
{

}

void App::timerEvent(int time)
{

}

但是如果我不想在某些情况下听timerEvent呢?我仍然需要编写空方法实现。

我的想法是从名称空间移动到class App : public BaseApp virtual void BaseApp::init() = 0virtual void BaseApp::timerEvent(int time) {} BaseApp(类似于Qt QApplication)。然而,App应该是单身,但我没有看到任何方式从BaseApp指定它,所以我必须在App中编写单例代码,所有虚拟的想法都没有意义。

我该如何设计?

P.S。我不想在这里使用听众。这对我来说似乎有点过分了。

P.P.S。我需要单例,因为我从main初始化应用程序实例,但仍想从其他类访问其方法。

1 个答案:

答案 0 :(得分:2)

您可以使用函数指针或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;
}