首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >GObject与继承

GObject与继承
EN

Stack Overflow用户
提问于 2018-01-17 16:48:32
回答 1查看 1.8K关注 0票数 1

我在做一些严肃的关于口齿不清的软件。我意识到有些话题我不太明白。IRC也帮不上忙所以..。

当我们进行继承时,我们可以有两个类。第一个A是直接从GObject继承的,B是从A继承的,然后我得出如下结论:

https://developer.gnome.org/gobject/stable/chapter-gobject.html

代码语言:javascript
复制
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->构造。这不是我们想要的。

也许我不明白,但我认为B中的记忆结构是这样的:

代码语言:javascript
复制
struct _B
{
  A parent_instance;

  /* instance members */
};

内部表示应该类似于:

代码语言:javascript
复制
[   Gobject struct memory ]
[                         ]
[   Gobject variables     ]
[   A struct memory       ]
[   A variables           ] 
[                         ]
[   B struct memory       ]
[   B variables           ] 

因此,在B中转换时的GObject内存是B和A类共享的。所有的地址都一样我..。

  • G_OBJECT_CLASS (B)->constructed
  • G_OBJECT_CLASS (A)->constructed

这是正确的吗?所以如果我想覆盖构造..。我是否必须保存以前的指针,然后用我的指针在init中覆盖它?这样我做完处理后就可以打电话给原来的那个了?

属性也是如此。因为A用枚举来定义它的属性,所以可以从0到N。

所以我认为B属性应该从N开始,而不是0。否则,A的属性将由B处理,并且可能使用不同的数据结构和名称。

检查这个:https://developer.gnome.org/gobject/stable/gobject-properties.html

代码语言:javascript
复制
enum
{
  PROP_FILENAME = 1,
  PROP_ZOOM_LEVEL,
  N_PROPERTIES
};

如果这两个类都用索引1定义了一个属性,那么就会出现一个问题,因为glib不知道谁应该处理。我想,子类B将处理它,但不正确,因为可能B正在等待,比如一个PROP_DIRECTORY,但是因为索引是相同的。滑翔能发送到正确的实例吗?

我只能做的事情,它将工作,如果在寄存器,胶质将添加一些偏移,取决于层次结构的水平。有人能解释一下这到底是怎么回事吗?我找不到任何需要技术细节的文件。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-01-18 10:04:19

内部表示应该类似于:

不完全是。GObjectGObjectClass结构之间有一个不同的地方。每个对象实例都有一个GObject结构实例,但整个类只有一个GObjectClass实例。

如果您有一个派生自GObject的类GObject,则FooBarClass结构看起来如下所示:

代码语言:javascript
复制
typedef struct
{
  GObjectClass parent_class;

  /* Virtual methods for FooBar instances: */
  void (*vfunc) (FooBar *self);
} FooBarClass;

堆上将有一个FooBarClass实例。因为它包含整个GObjectClass结构作为它的parent_class成员,这意味着它有自己的finalizedisposeget_property等虚拟方法指针。

另外,在堆中,有一个用于GObjectClass类型的GObject实例。它包含另一组finalizedispose等虚拟方法指针。

因为FooBar是从GObject派生的,所以foo_bar_parent_class将被设置为指向GObjectClass实例。这就是为什么可以把它们联系起来的原因。

因此,如果您想要实现constructed虚拟方法和连锁(您必须连锁constructed),只需做链接到的文档中的示例代码。这是正确的。

属性也是如此。因为A用枚举来定义它的属性,所以可以从0到N。

不正确。使用g_object_class_install_properties()向类注册属性时,属性索引将与该类的类结构中的GObjectClass实例关联。它们与GObjectClass类型的GObject结构无关.这是与上述相同的原则。

换句话说,没有全球范围的房地产指数登记:所有这些都是按类完成的。因此,您可以(并且应该)从1开始为每个类建立属性索引。他们不会发生冲突。

注意,正如g_object_class_install_properties()文档中所述,属性索引0是特殊的,不能使用。必须从1开始属性索引。

正如p番茄所说,这远远超出了文档的详细程度。你应该读一下源代码。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48306127

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档