【问题标题】:Initialize a GObject with parameters which are not GObject properties?使用不是 GObject 属性的参数初始化 GObject?
【发布时间】:2011-10-15 12:39:17
【问题描述】:

我有一个 GObject“A”,它在其构造函数中创建另一个 GObject“B”的实例。

“B”对象需要传递几个仅构造属性。现在,当创建对象“A”的实例时,我希望允许通过对象“A”的构造函数将这些属性的值传递给对象“B”的构造函数。

我发现这样做的唯一方法是为对象“A”创建相同的属性并将它们的值传递给“B”的构造函数。这些属性对“A”没有进一步的意义,所以这看起来像是一个杂物。

有没有更好的方法来做我想做的事?

【问题讨论】:

    标签: c glib gobject


    【解决方案1】:
    • A 继承自B。然后A 自动拥有B 的所有属性。
    • 不要使用A 中的属性,而是将B 的属性(或者更好的是,已经构造的B 对象)作为参数传递给A 的构造函数。
    • 延迟构造B 直到A 可以弄清楚它需要如何配置B。向Ab_initialized 或其他东西添加一个私有标志,告诉您A 指向B 的内部指针是否有效。

    关于第二个建议的更多说明:

    A 的东西是在 a_init() 函数中构造的,该函数由 G_DEFINE_TYPE() 宏提供。但这不是您获得A 实例的方式。通常写一个函数,它是A的公共接口的一部分,像这样:

    A *a_new() 
    {
        return (A *)g_object_new(TYPE_A, NULL);
    }
    

    您可以轻松扩展它以包含其他参数:

    A *a_new(int b_param_1, int b_param_2)
    {
        A *a = (A *)g_object_new(TYPE_A, NULL);
        a->priv->b = b_new(b_param_1, b_param_2);
        return a;
    }
    

    如果您使用g_object_new 构建它,例如,如果您尝试从 GtkBuilder 文件构建它,那么这会使您的 A 对象处于无效状态(即没有 B)。 .如果这是一个问题,我仍然强烈建议重构。

    【讨论】:

    • 不幸的是,两者完全不相关,这会“污染”对象“A”,而不仅仅是使用属性。
    • 对我来说听起来像是重构的主要候选人。不过,我会补充一些我想到的建议......
    • 将非属性参数传递给 A 的构造函数似乎符合我的兴趣。你有任何关于如何做到这一点的指针/示例吗?
    • 是的,但它需要延迟 B 的初始化,直到您实际创建 A 对象之后。我会在我的回答中添加一些提示。
    • 谢谢,我之前不太清楚你的意思。基本上这也是 Vala 所做的。由于我没有构建小部件,因此强制使用 _new 函数的限制不是问题。
    【解决方案2】:

    使用dependency injection,将一个已经初始化的B类型的对象传递给A的构造函数。

    这样,使用您的类的客户端可以决定是否传递不同类型的Bs(如果有意义的话,您甚至可以使用接口而不是类作为B 类型,编写代码针对接口通常比针对实现编写代码要好)。

    B 派生A 只有在它确实是其父类的特化时才有意义。

    从这个问题来看,推导是否有意义尚不清楚,但它通常是 overused method 用于组合。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-31
      • 2013-11-07
      • 1970-01-01
      相关资源
      最近更新 更多