【问题标题】:custom GUI objects自定义 GUI 对象
【发布时间】:2011-07-20 19:52:21
【问题描述】:

在 C++ 程序中,我有想要添加一些对象的图表。例如,它们可以是常见的“独立”对象,如文本、线条等,或者是更多不同类型的“智能”对象,它们的行为不同,可以连接到外部模型以读取/写入其状态。

我想到的最简单的事情是为所有具有Draw() 等虚函数的对象创建一个通用接口,但对象可以本质上不同(就像文本框和滚动条不同,因此具有不同的界面)。另一方面,如果我不创建通用接口,我将需要对对象类型进行分派,这在 C++ 中通常被认为是不好的做法。

所有这一切都应该保持简单,例如创建小部件和自定义消息队列将是一种矫枉过正,但我​​想让一些东西易于支持/扩展。

我知道 GUI 有很多模式,例如 MVC、MVP 等,但这些都是非常通用的,我有点迷茫,所以如果你能给我一些指导(或者更好,参考灵感来自) 那会很有帮助!谢谢。

【问题讨论】:

    标签: c++ user-interface visual-c++ architecture


    【解决方案1】:

    为了灵活性和可扩展性,您可以使用接口而不是单个基类。例如,扩展所有可以从 IDraw 接口绘制的对象。如果可以更新对象,则添加并实现 IControl 接口等等。这可能首先看起来是一种开销,但可以为您提供良好的可扩展性。

    编辑:

    void* Class::GetInterface(const int id)
    {
        if (IDraw::GetId() == id)
        {
            return (IDraw*)this;
        }
        else if (IControl::GetId() == id)
        {
            return (IControl*)this;
        }
    
        return NULL;
    }
    

    【讨论】:

    • 同样的问题 - 在这种情况下,如果没有动态类型分派,我怎么知道每个对象支持哪些接口?
    • 对于您经常使用的接口,将它们存储在列表中以避免动态转换的开销更有效,因为其余的可以毫无问题地使用。反正开销比较小。
    • 你可以通过使用类似 COM 的方法来避免 dynamic_cast:实现一个具有名为 GetInterface 的函数的基本接口,并像这样实现这个函数:我已经编辑了帖子以获得更好的格式
    • 嗯,你说的是对的,但实际上我知道不同的选项是什么,我的问题是选择一个好的模式。顺便说一句,你的例子看起来不对——想象一下如果Class 没有实现IControl 会发生什么。另请参阅我最近询问的有关 COM 样式转换的相关问题,以确保您不会浪费时间解释我已经知道的事情 :) stackoverflow.com/questions/4957739/is-static-cast-misused
    • 我的实现当然是针对实现IControl和IDraw的类。如果不支持这两个接口,则知道第三个它看起来会有所不同。我没有具体说明,因为这是非常经典的,我只是指出这个想法是使用 dynamic_cast 的一种变体。
    【解决方案2】:

    一种可能性是使用多重继承。定义一个 drawable 基类,该基类只定义了足以绘制可见对象的内容,并要求所有可绘制对象都从中派生。它们也可能(通常会)从其他基类派生,以定义它们支持的其他接口;这将确保可以在需要时绘制每个项目。

    【讨论】:

    • 但是我需要以某种方式猜测每个对象支持哪些接口。例如,如果对象存储在同质容器中(例如 list),我需要将其从包含的类型转换为每个接口。
    • @7vies:如果你有一个列表,那么objects在任何情况下都必须是相同的类型。在这种情况下,您可能需要list<drawable *> 来保存所有可绘制对象(或者您可能需要类似list<weak_ptr<drawable> > 的东西)。在任何情况下,它都需要是指针(类似)的东西,而不是对象本身,并且您只希望该集合中的可绘制派生对象开始。
    • @Jerry,当然,我的意思是指针,但如果我只有drawable* 的列表,我将如何支持其他接口 - 通过强制转换?然后我需要dynamic_cast、COM 的QueryInterface 或类似的东西......
    • 这就是为什么我建议使用weak_ptr——你几乎肯定想要一个可绘制对象的集合,以及用于其他目的的其他集合(可能包括指向相同实际对象的指针)。
    • 好的,我明白你的意思了,我也有这个按接口收集的想法,但觉得很奇怪:)
    猜你喜欢
    • 2018-09-04
    • 1970-01-01
    • 2016-10-08
    • 2011-04-14
    • 1970-01-01
    • 2023-03-31
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多