2016-05-15 78 views
2

我有一个棘手的循环包含问题,我不知道如何解决。综上所述:从Component
Component模板函数导致循环包含

​​继承实现在其头文件中的模板函数使用IApp::registerForEvent

我可以使用哪些技术或方法来解决/避免这种夹杂?

class Component; 
class IApp; 

class Component 
{ 
    IApp* app; 

    // Error: Invalid use of incomplete type 'class IApp' 
    template<typename T> 
    void registerEvent(const int& evtId, Status (T::*func) (int)) 
    { 
     auto res = std::bind(func, (T*)this, std::placeholders::_1); 
     app->registerForEvent(evtId); 
    } 
}; 

class IApp : public Component 
{ 
public: 
    void registerForEvent(const int& evtId) 
    { 
     printf("IApp::registerForEvent\n"); 

     // ... 
    } 
}; 
+0

如果您使用前向声明,则可以编译,但是通过询问“是IApp”是否真的是“Component”来解决问题? “我可以把IApp分成两类:一个是Component还是一个ComponentRegistry,或许?” (https://www.youtube.com/watch?v=_LEomvWXOiI) –

+0

我怀疑'IApp'既是一个接口又是一个单例。我强烈建议重新考虑这一点。你没有比下一个人更习惯使用更多模式的样式点(“有一天,我去了一个棕色袋子午餐,一位首席建筑师自豪地宣称他在一个项目中使用了每个GoF设计模式,他没有提到是因为该软件没有达到客户的期望,它不起作用。“http://baus.net/doersandtalkers;另请参阅https://code.google.com/archive/p/google-singleton -detector/wikis/FAQ.wiki) –

回答

8

在IApp之后定义registerEvent。

class IApp; 

class Component 
{ 
    IApp* app; 
    template<typename T> 
    void registerEvent(const int& evtId, Status (T::*func) (int)); 
}; 


class IApp : public Component { 
    ... 
}; 

template <typename T> 
Component::registerEvent(const int& evtId, Status (T::*func) (int)) { 
    auto res = std::bind(func, (T*)this, std::placeholders::_1); 
    app->registerForEvent(evtId); 
} 

如果有需要,还Component::registerEvent后定义A::registerEvent

4

你正试图在它的基类中使用派生类,这对我来说似乎不是一个好的设计方法。我建议将它移到其他两个班级都可以访问的班级。

2

您正在聚合Derived类对象。你可能因此解决循环依赖与奇怪的循环模板模式?

template <typename Aggregated> 
class Component 
{ 
    Aggregated* app; 

    template<typename T> 
    void registerEvent(const int& evtId, Status (T::*func) (int)) 
    { 
     auto res = std::bind(func, (T*)this, std::placeholders::_1); 
     app->registerForEvent(evtId); 
    } 
}; 

class IApp : public Component<IApp> 
{ 
public: 
    void registerForEvent(const int& evtId) 
    { 
     printf("IApp::registerForEvent\n"); 

     // ... 
    } 
}; 

不过,我不清楚你在做什么。对于你认为传递的函数Component :: registerEvent是Component的成员(你绑定到(T *)this),同时将事件ID委托给聚集的IApp。对我来说,似乎重新思考你的设计也可能解决循环依赖问题?