Initialiser un GObject avec des parameters qui ne sont pas des propriétés de GObject?

J’ai un GObject “A” qui crée une instance d’un autre GObject “B” dans son constructeur.

L’object “B” doit être transmis à plusieurs propriétés de construction uniquement. Maintenant, lors de la création d’une instance d’object “A”, je souhaite autoriser la transmission des valeurs de ces propriétés par le constructeur de l’object “A” au constructeur de l’object “B”.

Le seul moyen que j’ai trouvé pour cela était de créer des propriétés identiques pour l’object “A” et de transmettre leurs valeurs au constructeur de “B”. Ces propriétés n’auraient plus aucune signification pour “A”, cela ressemble donc à un kludge.

Y a-t-il une meilleure façon de faire ce que je veux?

  • Avoir A hériter de B Alors A a toutes les propriétés de B automatiquement.
  • N’utilisez pas de propriétés dans A , mais transmettez plutôt les propriétés de B (ou même un object B déjà construit) en tant que parameters au constructeur de A
  • Retarder la construction de B jusqu’à ce que A sache comment configurer B Ajoutez un indicateur privé à A , b_initialized ou quelque chose qui indique si le pointeur interne de B sur B est valide.

Quelques précisions supplémentaires sur la deuxième suggestion:

A a_init() A est construit dans la fonction a_init() fournie par la macro G_DEFINE_TYPE() . Mais ce n’est pas ainsi que vous obtenez une instance de A Il est habituel d’écrire une fonction qui fait partie de l’interface publique de A , comme ceci:

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

Vous pouvez facilement l’étendre pour inclure d’autres 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; } 

Cela présente l’inconvénient de laisser votre object A dans un état non valide (sans B ) si vous le construisez à l’aide de g_object_new , par exemple si vous essayez de le construire à partir d’un fichier GtkBuilder. Si cela pose un problème, je suggère toujours fortement de refactoriser.

Utilisez l’ dependency injection , transmettez un object déjà initialisé de type B au constructeur de A

De cette façon, le client qui utilise votre classe peut décider de passer ou non différents types de B s (s’il est logique de pouvoir utiliser une interface au lieu d’une classe comme type B , l’écriture de code contre des interfaces est généralement préférable à l’écriture de code contre les implémentations).

Dériver A de B n’a de sens que s’il s’agit vraiment d’une spécialisation de sa classe parente.

De la question, il n’est pas clair si la dérivation a un sens, mais c’est une méthode de composition souvent trop utilisée .