c ++工厂模式

时间:2011-11-10 16:03:57

标签: c++ factory-pattern

我很抱歉长篇文章,但我想提出我试图解决的问题以及实际问题。也许我会指出另一种可能更好的方法。

我想创建一个eventtriggerred处理程序系统。我将有几个处理程序模块。基本思想是在初始化期间,这些模块将在事件列表中注册它们处理的事件(register(module,eventItGetsCalledFor))。在触发事件的情况下,将在事件列表中查找该事件,并创建并运行其中列出的所有模块。为实现这一目标,所有模块都有一个接口。

我的两个问题是:

  1. 由于我只想在实际事件上实例化模块,我需要一种方法来存储指向构造函数的指针(“虚拟构造函数”),因为据我所知,我没有虚拟构造函数使用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类,将其包装在模板中并从中继承)

  2. 第二个问题是我有从我的接口类派生的不同类。但是,它们具有未在接口中定义的成员。我想将一个functionpointer存储到一个成员函数,我该怎么做?类型必须接受不同的基类,但函数签名的其余部分是相同的(参见下面的示例)

    class A : public interface {
         void myFunc()
    };
    
    class A : public interface {
         void yourFunc()
    };
    
    whatType* a = &A::myFunc;
    whatType* b = &B::yourFunc;
    

2 个答案:

答案 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)

  1. 静态成员函数不会将 this 指针作为非静态成员函数的第一个参数,因此静态成员函数可以被视为特定命名空间中的全局函数。这就是不能这样写的原因:

      

    static virtual * myInterface builder()= 0;

  2. 无法定义类似的函数类型。如果有不同类但具有相同签名的函数,请考虑使用新接口继承第一个接口并将虚拟成员添加到新接口。当您获得基接口指针时,使用 dynamic_cast 从基接口指针获取原始类型指针,然后调用新的成员函数。或者,您可以尝试Boost::Bind。这对你的情况似乎很有帮助。