2016-03-12 74 views
3

我正在编写用C++编写的简单框架。现在我有一些像用虚拟方法组织单身人士的最佳方法

app.cpp

#include "app.h" 

namespace App 
{ 

} 

void App::init() 
{ 

} 

void App::timerEvent(int time) 
{ 

} 

但是,如果我不想要听timerEvent在某些情况下是什么?我仍然必须写空方法实现。

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

我应该如何设计它?

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

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

+3

我不明白一切,但在任何情况下,只要不使用单例,并基于该原理设计的架构。 –

+0

您可以*选择*仅创建**一个** App对象。你不需要一个单身人士来做出选择。 – Galik

+0

@加利克,但我没有看到任何其他的可能性。我想从另一个代码部分调用我的应用程序实例方法。 – Ximik

回答

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

这不是很好的设计,但它做你想做的。

UPDATE

另一个近似:

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

谢谢,第二个答案只是100%正确。 – Ximik