我正在研究用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) {}(类似于Qt BaseApp)从 namespace 移动到QApplication。但是,App应该是单例的,但是我看不到从BaseApp指定它的任何方法,因此我必须在App中编写单例代码,所有虚拟想法都没有意义。

我应该如何设计?

附言我不想在这里使用监听器。对我来说似乎太过分了。

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

最佳答案

您可以使用函数指针或std::function在 namespace 中模拟虚拟函数。只是做这样的事情:

#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;
}

10-08 16:18