2016-03-12 101 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