Initialize a GObject with parameters which are not

2019-05-14 02:34发布

问题:

I have a GObject "A" which creates an instance of another GObject "B" in its constructor.

The "B" object needs to be passed several construction-only properties. Now when creating an instance of object "A" I want to allow passing values for these properties through the constructor of object "A" on to the constructor of object "B".

The only way I have found to do that was to create identical properties for object "A" and pass their values on to the constructor of "B". These properties would have no further meaning to "A" so this seems like a kludge.

Is there a better way to do what I want?

回答1:

  • Have A inherit from B. Then A has all of B's properties automatically.
  • Don't use properties in A, but instead pass B's properties (or even better, an already-constructed B object) as parameters to A's constructor.
  • Delay construction of B until A can figure out how it nees to configure B. Add a private flag to A, b_initialized or something, that tells you whether A's internal pointer to B is valid.

Some more clarification on the second suggestion:

A's stuff is constructed in the a_init() function that is provided for by the G_DEFINE_TYPE() macro. But that's not how you get an instance of A. It's usual to write a function, which is part of the public interface of A, like this:

A *a_new() 
{
    return (A *)g_object_new(TYPE_A, NULL);
}

You can easily extend this to include other parameters:

A *a_new(int b_param_1, int b_param_2)
{
    A *a = (A *)g_object_new(TYPE_A, NULL);
    a->priv->b = b_new(b_param_1, b_param_2);
    return a;
}

This has the disadvantage of leaving your A object in an invalid state (i.e., without a B) if you construct it using g_object_new, for example if you're trying to build it from a GtkBuilder file. If that's a problem, I still strongly suggest refactoring.



回答2:

Use dependency injection, pass an already initialized object of type B to the constructor of A.

That way the client that is using your class can decide whether to pass in different kinds of Bs (if it makes sense you can even use an interface instead of a class as the B type, writing code against interfaces is generally better than writing code against implementations).

Deriving A from B only makes sense if it really is a specialization of it's parent class.

From the question it isn't clear if derivation makes sense, but it's an often overused method for composition.



标签: c glib gobject