我在做一些严肃的关于口齿不清的软件。我意识到有些话题我不太明白。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->构造。这不是我们想要的。
也许我不明白,但我认为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类共享的。所有的地址都一样我..。
这是正确的吗?所以如果我想覆盖构造..。我是否必须保存以前的指针,然后用我的指针在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,但是因为索引是相同的。滑翔能发送到正确的实例吗?
我只能做的事情,它将工作,如果在寄存器,胶质将添加一些偏移,取决于层次结构的水平。有人能解释一下这到底是怎么回事吗?我找不到任何需要技术细节的文件。
发布于 2018-01-18 10:04:19
内部表示应该类似于:
不完全是。GObject和GObjectClass结构之间有一个不同的地方。每个对象实例都有一个GObject结构实例,但整个类只有一个GObjectClass实例。
如果您有一个派生自GObject的类GObject,则FooBarClass结构看起来如下所示:
typedef struct
{
GObjectClass parent_class;
/* Virtual methods for FooBar instances: */
void (*vfunc) (FooBar *self);
} FooBarClass;堆上将有一个FooBarClass实例。因为它包含整个GObjectClass结构作为它的parent_class成员,这意味着它有自己的finalize、dispose、get_property等虚拟方法指针。
另外,在堆中,有一个用于GObjectClass类型的GObject实例。它包含另一组finalize、dispose等虚拟方法指针。
因为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番茄所说,这远远超出了文档的详细程度。你应该读一下源代码。
https://stackoverflow.com/questions/48306127
复制相似问题