【问题标题】:an alternative to floating references to GObject对 GObject 的浮动引用的替代方法
【发布时间】:2017-07-28 18:58:41
【问题描述】:

我正在阅读lecture on GTK+ memory management,“对象从GInitiallyUnowned 下降”一章。引入了浮动引用的概念,方便我们编写代码

container = create_container();
container_add_child(container, create_child());

而不是

Child *child;
container = create_container();
child = create_child();
container_add_child(container, child);
g_object_unref(child);

我立刻意识到,同样可以实现如下。有一个函数container_add_child_move_ownershipcontainer_add_child 是多余的。假设container_add_child_move_ownership(container, child) 将所有权从调用者转移到container,因此container_add_child_move_ownership 不会更改引用计数。因此,下面的例子是正确的。

void f(Container *container) {
    container_add_child_move_ownership(container, create_child());
}

要么 0) 我的解决方案有一个我看不到的缺陷,要么 1) 浮动引用的概念是一个糟糕的设计决策。哪个是真的?

【问题讨论】:

    标签: memory-management garbage-collection gobject


    【解决方案1】:

    StackOverflow 真的不是与 GObject 和 G* 平台的 API 设计者讨论这个问题的好方法;您可能想在gtk-devel 邮件列表中询问。

    是的,浮动引用只是进行所有权转移的一种奇特方式。

    “移动所有权”API 方法的问题在于,指针所有权没有明确定义的类型语义。你根本不知道——除非你像container_add_with_ownership_transfer()这样尴尬地命名你的API——事先。此外,这意味着某些 API 适用于所有权转移,但无法通过类型检查发现。这对于语言绑定尤其至关重要,因为它们需要了解所有权转移规则。

    最近,GObject 获得了额外的注解用于自省目的,但是修改 API 和类型系统当然为时已晚。

    【讨论】:

      【解决方案2】:
      1. 我的解决方案有一个我看不到的缺陷

      您的解决方案的问题是您必须创建两个函数:

      • container_add_child.
      • container_add_child_move_ownership。

      考虑一个您不想转移所有权的情况。在这种情况下,您有两种选择:

      1. 在将对象移入函数之前增加对象的引用计数:

      container_add_child_move_ownership(container, g_object_ref(child))

      1. 添加另一个不会移动所有权的函数:

      container_add_child(container, child)

      使用浮动引用,您只有一个适用于两种情况的函数。

      1. 浮动引用的概念是一个糟糕的设计决策。

      就我个人而言,是的,这是糟糕的设计。您的移动所有权解决方案比浮动引用的解决方案更清晰,即使您必须创建两个函数(但我会为移动函数命名,如 container_add_child_mv)。

      对于浮动引用,您必须考虑 which function to use g_object_ref_sink 或只是 g_object_ref。对于浮动引用,您必须handle potentially floating parameters carefully

      即使是 GLib 文档也有关于浮动引用的 note

      注意:浮动引用是一种 C 便利 API,不应在现代 GObject 代码中使用。语言绑定尤其发现这个概念存在很大问题,因为浮动引用无法通过注释来识别,而且浮动引用行为的偏差也不是,例如从 GInitiallyUnowned 继承并仍然从 g_object_new() 返回完整引用的类型。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-05-23
        • 2023-02-03
        • 2018-10-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-12-04
        相关资源
        最近更新 更多