c++ - C++ 中的通用(几乎)自描述参数与 GUI 相结合?

标签 c++ oop templates

我面临以下难题:我们的软件有一个算法对象的抽象基类。所有这些对象都有一个共同的 execute() 方法,例如:

class Algorithm
{
public:
  // [...]
  virtual void execute() = 0;
  // [...]
};

对于我们想要实现的每个算法,我们只需从基类继承并将所有加载的算法对象存储在一个中央位置。到目前为止,还不错。

现在的问题在于算法的参数。我们希望能够为每个算法描述需要设置的参数(由外部类)。为此,我们为每个算法提供了一个包含其参数的 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;
};

您可以像这样定义子类:

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* 的列表。然后,您可以通过实例化适当的访问者类型来构建 GUI,然后让其 visit 回调执行所有小部件构建。这最终是类型安全的并恢复您需要的信息。它确实有一个缺点,即每次创建新的参数类型时,都必须向 ParameterVisitor 类添加一个新的成员函数 visit,但是您需要这样做无论如何都要完成所有 GUI 构建。

希望这对您有所帮助!

关于c++ - C++ 中的通用(几乎)自描述参数与 GUI 相结合?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10607486/

相关文章:

c++ - 放置新行为等效

c++ - Windows 上的 boost.asio 错误代码是平台相关的?

c++ - c/c++中两个函数内容相同时,哪种风格更好?

c# - 我应该在哪里放置功能以在类型之间进行转换?

c++ - 如何从模板化类方法返回依赖类型?

c++ - 字符数组和指针的基本混淆

javascript - 为什么 JavaScript 原始变量不可变而对象变量不可变?

api - REST 会破坏数据封装吗?

c++ - 限制模板功能

c++ - 模板化静态成员函数是如何解析的?