Gno*_*lon 11 c++ oop templates
我面临以下难题:我们的软件有一个算法对象的抽象基类.所有这些对象都有一个共同的execute()方法,例如:
class Algorithm
{
public:
  // [...]
  virtual void execute() = 0;
  // [...]
};
Run Code Online (Sandbox Code Playgroud)
对于我们想要实现的每个算法,我们只是从基类继承并将所有加载的算法对象存储在一个中心位置.到现在为止还挺好.
现在的问题在于算法的参数.我们希望能够为每个算法描述需要设置的参数(由外部类).为此,我们为每个算法提供了一个ParameterList包含其参数的对象.我应该澄清一下,对于我们来说,参数由某种类型(例如int)和标签(例如"迭代次数")组成.
现在,当我们想要连接ParameterList到某种GUI 时,问题就开始了.显然,我们的算法应该没有我们正在使用的图形API(Qt,GTK等)的"知识".然而,在同一方面,我们希望能够在语义上描述算法参数,例如通过指定算法需要文件名.然后如何显示此文件名取决于GUI.
有没有办法将它ParameterList与某种语义类型的知识结合起来?
我意识到这个问题听起来很模糊.但是,我不允许发布任何非平凡的代码示例(出于NDA原因).那么,过去有没有人遇到过类似的问题?
包装起来:我们希望我们的对象能够描述GUI所需的参数,而不需要知道GUI的确切细节.
这里的一个选择可能是使用访问者模式.您可以像这样创建一个基类:
class Parameter {
public:
    virtual ~Parameter() {} // Polymorphic classes need virtual dtors.
    virtual void accept(ParameterVisitor& v) = 0;
};
Run Code Online (Sandbox Code Playgroud)
您可以像这样定义子类:
class IntParameter: public Parameter {
public:
     virtual void accept(ParameterVisitor& v) {
          v.visit(*this);
     }
};
class FilenameParameter: public Parameter {
public:
     virtual void accept(ParameterVisitor& v) {
          v.visit(*this);
     }
};
Run Code Online (Sandbox Code Playgroud)
请注意,在每个accept成员函数中,类型*this是类的静态类型 - 即,IntParameter&在第一种情况下,FilenameParameter&在第二种情况下.
然后,您可以ParameterVisitor像这样定义基类类:
class ParameterVisitor {
public:
    virtual ~ParameterVisitor() {} // Polymorphic classes need virtual dtors.
    virtual void visit(IntParameter& p) {}
    virtual void visit(FilenameParameter& p) {}
    /* .. etc. .. */
};
Run Code Online (Sandbox Code Playgroud)
然后,您可以将此访问者子类化以获取类型信息:
class Gui1ParameterVisitor: public ParameterVisitor {
public:
    virtual void visit(IntParameter& p) {
        /* ... use GUI1 to create a field for an integer. */
    }
    virtual void visit(FilenameParameter& p) {
        /* ... use GUI1 to create a field for a filename. */
    }
};
class Gui2ParameterVisitor: public ParameterVisitor {
public:
    virtual void visit(IntParameter& p) {
        /* ... use GUI2 to create a field for an integer. */
    }
    virtual void visit(FilenameParameter& p) {
        /* ... use GUI2 to create a field for a filename. */
    }
};
Run Code Online (Sandbox Code Playgroud)
ParameterList然后,您的班级可以只存储一个Parameter*s 列表.然后,您可以通过实例化适当的访问者类型然后让其visit回调执行所有窗口小部件构建来构建GUI .这最终是类型安全的,并恢复您需要的信息.它有你每次创建新的参数类型,你有一个新的成员函数添加缺点visit的ParameterVisitor类,但你需要做的是反正做所有的GUI构建.
希望这可以帮助!