我有一个棘手的循环包含问题,我不知道如何解决。总结一下:
的模板化函数
IApp
继承自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 :(得分: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);
}
如果需要,还可以在A::registerEvent
之后定义Component::registerEvent
。
答案 1 :(得分:4)
你试图在它的基类中使用派生类,这对我来说似乎不是一个好的设计方法。我建议将它移到其他类可以访问的其他类中。
答案 2 :(得分:2)
您正在聚合派生类对象。因此,您可以通过奇怪的重复模板模式解决循环依赖性?
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。对我来说,似乎重新思考你的设计也可以解决循环依赖问题?