Initialize a GObject with parameters which are not GObject properties?
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 constru开发者_如何转开发ctor 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?
- Have
A
inherit fromB
. ThenA
has all ofB
's properties automatically. - Don't use properties in
A
, but instead passB
's properties (or even better, an already-constructedB
object) as parameters toA
's constructor. - Delay construction of
B
untilA
can figure out how it nees to configureB
. Add a private flag toA
,b_initialized
or something, that tells you whetherA
's internal pointer toB
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.
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 B
s (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.
精彩评论