这里的一种选择可能是使用访问者模式。您可以像这样创建一个基类:
class Parameter {
public:
virtual ~Parameter() {} // Polymorphic classes need virtual dtors.
virtual void accept(ParameterVisitor& v) = 0;
};
您可以定义如下子类:
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);
}
};
请注意,在每个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. .. */
};
然后,您可以对该访问者进行子类化以获取类型信息:
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. */
}
};
然后,您的ParameterList
班级可以只存储Parameter*
s 的列表。然后,您可以通过实例化适当的访问者类型来构建 GUI,然后让其visit
回调完成所有小部件的构建。这最终是类型安全的并恢复了您需要的信息。它确实有一个缺点,即每次创建新的参数类型时,都必须向类中添加新的成员函数visit
,ParameterVisitor
但无论如何您都需要这样做才能完成所有 GUI 构建。
希望这可以帮助!