vala如何允许定义没有默认构造函数的GObject?

时间:2016-09-20 22:40:31

标签: vala gobject

Vala tutorial表明类可以用GObject样式或类似于Java / C#等的样式用构造函数编写。

本教程显示这完全独立于该类是否继承自Glib.GObject。(编辑:我对Glib.Object和{{1}之间的教程切换感到困惑在Vala中有一个隐含的Object,所以两者是相同的。)

我认为如果没有默认构造函数(使用Java / C#样式)定义Glib.GObject子类,我必须为GObject定义隐式默认构造函数,可能会使所有字段都填充二进制零(根据GObject初始化)?

另见Initialize a GObject with parameters which are not GObject properties?

2 个答案:

答案 0 :(得分:1)

Vala会自动在C代码中创建一个构造函数。这遵循* _new命名模式。所以最简单的例子是:

void main () {
    new ExampleWithoutExplicitConstructor ();
}

class ExampleWithoutExplicitConstructor {
}

如果您使用valac --ccode example.vala对其进行编译并查看生成的C代码,则会看到_vala_main次调用example_without_explicit_constructor_new (),然后调用example_without_explicit_constructor_construct ()example_without_explicit_constructor_construct ()然后为该类型调用g_object_new ()。作为g_object_new创建类型的一部分,它将调用example_without_explicit_constructor_instance_init (),其中任何变量都可以初始化。

这是一个继承自Object的更复杂的示例,因此是一个完整的GObject类,具有默认值的字段和具有默认值的属性:

void main () {
    new ExampleWithoutExplicitConstructor ();
}

class ExampleWithoutExplicitConstructor:Object {
    private string example_field = "default";

    public string an_object_property { get; 
        set; 
        default = "this object properties default string";
        }
}

您会从C代码中注意到_new_constructg_object_new_instance_init模式是相同的。 Vala所做的是设置_instance_init来初始化字段和属性的默认值。

没有默认值的公共字段为空。您将看到它们出现在包含实例数据的struct的定义中。私有字段类似,但保存在实例的私有struct中。你可以通过玩这个例子来看到这个。

答案 1 :(得分:0)

让我们找出valac -C

示例代码:

class MySuper : Object
{
    private int i;
    private int j;

    public MySuper (int i)
    {
        this.i = i;
        j = 1;
    }
}

class MyDerived : MySuper
{
    public MyDerived ()
    {
        base (10);
    }
}

生成的C代码的(相关部分)如下所示:

MySuper* my_super_construct (GType object_type, gint i) {
    MySuper * self = NULL;
    gint _tmp0_ = 0;
    self = (MySuper*) g_object_new (object_type, NULL);
    _tmp0_ = i;
    self->priv->i = _tmp0_;
    self->priv->j = 1;
    return self;
}


MySuper* my_super_new (gint i) {
    return my_super_construct (TYPE_MY_SUPER, i);
}


MyDerived* my_derived_construct (GType object_type) {
    MyDerived * self = NULL;
    self = (MyDerived*) my_super_construct (object_type, 10);
    return self;
}


MyDerived* my_derived_new (void) {
    return my_derived_construct (TYPE_MY_DERIVED);
}

valac产生的一些假设:

  • MySuper和MyDerived都获得了_construct_new功能。
  • my_super_construct仅拨打g_object_new
  • my_derived_construct仅调用my_super_construct(后者调用g_object_new

所以Vala编译器很好地链接了所有内容,并且C#/ Java样式构造函数被转换为GObject样式的构造。

关于成员的初始化:如果你不在Vala代码中提供初始化,那么生成的构造函数也不会初始化任何东西。

所有这些都是在Vala幕后为您完成的。您不应该担心代码生成的细节,但是如果您希望您始终可以使用-C ...