【发布时间】:2018-01-17 16:48:32
【问题描述】:
我在 Glib 上做一些严肃的软件。我意识到有些话题我并不真正理解。 IRC 也没有帮助...
当我们进行继承时,我们可以有两个类。第一个A直接继承自GObject,B继承自A。然后我来了:
https://developer.gnome.org/gobject/stable/chapter-gobject.html
static void
viewer_file_constructed (GObject *obj)
{
/* update the object state depending on constructor properties */
/* Always chain up to the parent constructed function to complete object
* initialisation. */
G_OBJECT_CLASS (viewer_file_parent_class)->constructed (obj);
}
static void
viewer_file_class_init (ViewerFileClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
object_class->constructed = viewer_file_constructed;
}
但是当你有这种安排时。子类这样做:object_class->constructed = viewer_file_constructed;在 B 中重写实际上是构造的唯一内存地址。所以这意味着 G_OBJECT_CLASS (viewer_file_parent_class)->constructed (obj);将递归调用 B->constructed。这不是我们想要的。
也许我不明白,但我想B中的内存结构是这样的:
struct _B
{
A parent_instance;
/* instance members */
};
内部表示应该是这样的:
[ Gobject struct memory ]
[ ]
[ Gobject variables ]
[ A struct memory ]
[ A variables ]
[ ]
[ B struct memory ]
[ B variables ]
所以在 B 中转换时的 GObject 内存是由 B 和 A 分类共享的。并且所有地址都在同一个 i...
- G_OBJECT_CLASS (B)->构造
- G_OBJECT_CLASS (A)->已构建
这是正确的吗? 所以如果我想覆盖构造......我是否必须保存之前的指针,然后用我的 init 覆盖它?所以我可以在处理完后调用原始的?
这同样适用于属性。因为 A 通过枚举来定义它的属性,所以可以从 0 到 N。
所以我认为 B 属性应该从 N 开始,而不是 0。否则 A 的属性由 B 处理,并且可能具有不同的数据结构和名称。
检查这个: https://developer.gnome.org/gobject/stable/gobject-properties.html
enum
{
PROP_FILENAME = 1,
PROP_ZOOM_LEVEL,
N_PROPERTIES
};
如果两个类都定义了索引为 1 的属性。那会有问题,因为 glib 不知道应该处理谁。我想子类 B 会处理它但不正确,因为可能 B 正在等待,比如 PROP_DIRECTORY,但因为索引是相同的。 glib 能否发送到正确的实例?
只有在寄存器 glib 会根据层次结构级别添加一些偏移量时,它才会起作用。有人可以解释一下这是如何工作的吗?我找不到任何具有所需技术细节的文档。
【问题讨论】:
-
可能你得到答案的唯一方法就是查看源代码......
-
GLib 已经存在 20 多年了。它的官方文档和它一样,是稳定的,并且变化相对缓慢。你应该假设这些官方文档知道他们在说什么,而不是认为你是第一个突然发现这种根本性的、完全破坏性错误的人......在这种情况下,你应该假设你误解了,需要阅读更多,并不是说文档是错误的。不是。
标签: inheritance glib gobject