我很抱歉长篇文章,但我想提出我试图解决的问题以及实际问题。也许我会指出另一种可能更好的方法。
我想创建一个eventtriggerred处理程序系统。我将有几个处理程序模块。基本思想是在初始化期间,这些模块将在事件列表中注册它们处理的事件(register(module,eventItGetsCalledFor))。在触发事件的情况下,将在事件列表中查找该事件,并创建并运行其中列出的所有模块。为实现这一目标,所有模块都有一个接口。
我的两个问题是:
由于我只想在实际事件上实例化模块,我需要一种方法来存储指向构造函数的指针(“虚拟构造函数”),因为据我所知,我没有虚拟构造函数使用Factory方法,我想添加到界面。我所知道的经典方法是:
class myInterface {
public:
...
static virtual *myInterface builder() = 0; //is static (pure) virtual possible?
};
class example : public myInterface {
public:
...
static virtual *myInterface builder() { return new example(); }
};
然后我必须在事件列表中存储指向builder()函数的指针,并在事件发生时执行函数以创建对象。我想知道是否有一种方法为每个示例模块编写static virtual *myInterface builder() { return new example(); }
。
模板方法就是这样说:
模板 static virtual * myInterface builder(){return new T(); }
但是我不喜欢它,因为我必须编写以下内容来注册事件的模块:
寄存器(eventName的,助洗剂())
考虑到我想在每个模块中只创建一个静态寄存器函数,如下所示:
class example: public myInterface {
static void registerMe {
register(event1,builder<example>());
register(event2,builder<example>());
...
register(eventn,builder<example>());
}
};
如果像register(event)
这样的通话就足够了,那会更方便。
我可以在接口上添加register(event)
,但我不想为每个读取的模板重写注册函数
void register(event) { getListForEvent(event).pushBack(builder<example>()); }
(构建器 - 模板实例化参数不同),并且使其成为模板本身也不是很好,因为这会让我回到一遍又一遍地写register<myclass>()
。
那么有更方便的方式吗? (在思考和写作期间,我提出继承自模板类。如果polimorphism与具有不同实例化参数的模板类一起使用。否则我必须使用Interface类,将其包装在模板中并从中继承)
第二个问题是我有从我的接口类派生的不同类。但是,它们具有未在接口中定义的成员。我想将一个functionpointer存储到一个成员函数,我该怎么做?类型必须接受不同的基类,但函数签名的其余部分是相同的(参见下面的示例)
class A : public interface {
void myFunc()
};
class A : public interface {
void yourFunc()
};
whatType* a = &A::myFunc;
whatType* b = &B::yourFunc;
答案 0 :(得分:3)
//静态(纯)虚拟可能吗?
没有
CRTP (Curiously recurring template pattern)救援
template <class Derived>
class myInterface {
public:
...
virtual *myInterface builder() = 0;
Derived* buildDerived()
{
return dynamic_cast<Derived*>(builder());
}
};
答案 1 :(得分:1)
静态成员函数不会将 this 指针作为非静态成员函数的第一个参数,因此静态成员函数可以被视为特定命名空间中的全局函数。这就是不能这样写的原因:
static virtual * myInterface builder()= 0;
无法定义类似的函数类型。如果有不同类但具有相同签名的函数,请考虑使用新接口继承第一个接口并将虚拟成员添加到新接口。当您获得基接口指针时,使用 dynamic_cast 从基接口指针获取原始类型指针,然后调用新的成员函数。或者,您可以尝试Boost::Bind。这对你的情况似乎很有帮助。