137Fermer139
SasumeLe 26/04/2010 à 11:38
Kevin Kofler (./129) :
Sasume (./127) :
Bof, ça revient exactement au même, en plus lourd et moins bien.

En C++, c'est plus efficace (plus rapide, code plus compact, fonctionne même quand on compile sans RTTI => moins d'overhead) qu'un dynamic_cast, et n'a pas besoin de métaobjets Qt comme qobject_cast ou QObject::inherits.
Oui, c’est juste, en fait je voulais dire moins lourd à écrire et à maintenir. Utiliser une fonction du langage est plus sûr et pratique.
Folco (./130) :
1. La transmission d'informations.

Mon gestionnaire de tâches est à la racine de tous les objets : il crée des modules, qui créent des Plane, des icônes, des évènements, des listes, des avions, bref de tout. Mais (puisqu'il y a un mais, je l'ai donc mis là). Mais ce sont les icônes qui vont provoquer un changement de tâche. C'est en effet en cliquant sur un icône ou une autre qu'on va quitter un module et demander le chargement d'un autre. Alors comment faire communiquer l'icône avec le gestionnaire de tâches ? Ou la méthode manageIcon(MouseX, MouseY) renvoie un numéro de tâche à charger s'il y en a un, et le module doit le renvoyer à son tour au gestionnaire de tâche, ou... quoi d'autre ?
Personnellement, je trouve ça très moche le fait de faire transiter une information par tous les objets qui auront été créés entre le gestionnaire et l'icône... J'aurais alors des objets qui n'ont rien à faire des tâches qui se retrouvent à jouer les facteurs ? C'est hyper moche. J'ai pensé alors à une sorte d'"objet global", comme une variable globale, qui servirait de boite au lettre pour les uns et les autres, et que le gestionnaire viendrait relever quand ça lui plairait. Mais l'idée ne m'attire pas plus, même si ça me semble déjà mieux.

Comment feriez-vous ? Je ne dois pas être le premier à vouloir renvoyer une info quelque part sans emmerder tout le monde entre le départ et l'arrivée. hehe
Ce n’est clairement pas une bonne idée que tes icônes aient connaissance des planes et tout le tralala. C’est une bonne idée de réduire chaque classe à une seule tâche, une seule responsabilité. Celle de l’icône, ça peut être d’afficher quelque chose sur un screen (via sa méthode paint, si je me souviens bien) et d’exécuter une « action » quand il est cliqué. L’action pourrait être n’importe quoi, comme changer de module ou déclencher un tir sur un ennemi, ou que sais-je.

Une façon simple de faire ça c’est de configurer ton bouton à l’initialisation en lui passant en paramètre l’action à réaliser. Et au moment convenu, le bouton exécutera l’action. Qu’est-ce qu’une Action ? Ça peut être une classe abstraite (ce qu’on appelle une interface en conception objet) qui contient une opération virtuelle pure (abstraite) : execute(). Tu pourras ainsi simplement créer une classe pour chaque action, lui faire implémenter l’opération execute() où tu lui feras faire ce que tu voudras, et ensuite passer une instance de cet classe en paramètre à ton icône, qui se chargera d’appeler sa méthode execute.

Graphiquement, ça donne cette architecture :
tromb Fichier joint : WrUD (action.png)

Tu peux aussi jeter un coup d’œil au Design Pattern [url=http://en.wikipedia.org/wiki/Command Pattern]Command[/url]

Le problème de cette façon de faire c’est que ça te fera écrire beaucoup de classes (vu qu’en C++ on ne peux pas écrire de classes anonymes…), donc prendra pas mal de temps de développement…

Sinon, une façon très confortable de résoudre le problème est d’utiliser un mécanisme de signals/slots, similaire à celui fournit par Qt ou Boost. C’est un peu plus long à coder (sauf si tu utilises directement celui de Boost), mais c’est très pratique, tu peux directement relier un événement (l’activation d’une icône) à n’importe quelle méthode de ta classe (donc tu as juste besoin d’écrire une opération par action, et pas une classe).
2. Héritage, classe sans occurrence

J'ai donc une classe Module qui sert de base à des StaticModule et des BattleModule. Donc je ne vais avoir aucun objet Module à proprement parler (un Objet module se baladant seul, quoi), mais plusieurs objets greffés sur des Modules.
a. Question de principe : si je veux simplifier un minimum quelques tâches, est-ce propre de mettre pas mal d'attributs en protected dans Module pour ne pas jouer de l'accesseur tous les 2 minutes pour ? C'est considéré comme propre ce concept ? Ca peut être dangereux ?
b. Que dois-je implémenter comme méthodes ? Que dois-je définir comme virtual ? Je sens qu'ici il y a des choix à faire, mais je n'en maitrise absolument pas les tenants et aboutissants... Si vous vouliez bien m'éclairer, ce serait très aimable à vous. cheeky
Souane a déjà répondu, mais j’ai envie d’apporter aussi mon témoignage smile Le passage d’attributs d’une visibilité private à protected peut se justifier si tu estimes que les sous-classes auront légitimement accès à cet attribut. Après, forcément, ça atténue l’encapsulation de la classe mère et crée un couplage fort entre celle-ci et ses sous-classes (si tu modifies un peu la classe mère tu risqueras d’avoir à modifier les sous-classes aussi). Mais ne t’inquiète pas, ce n’est pas diabolique d’introduire du couplage de temps en temps, il faut juste en être conscient.
[cite]
Folco (./132) :
Oui. Mais dans quel cas faire des méthodes virtuelles ? Dans quel cas redéfinir certaines méthodes etc ? Est-ce que je vais utiliser des méthodes abstraites parce que c'est le seul moyen que me donne C++ pour faire les héritages que je veux, ou parce que stratégiquement c'est mieux pour mon programme ?
Tu ne devrais passer en virtual que les méthodes dont tu estimes qu’elles devraient pouvoir être redéfinies par les sous-classes. Si tu ne veux pas qu’une sous-classe puisse redéfinir le comportement d’une méthode tu ne mets pas virtual.
En pratique je trouve que c’est assez agréable que tout soit virtual (comme en Java ou Python).
Et maintenant que j'y pense, puisque je n'ai que deux types de classes filles, pourquoi ne pas écrire de classe mère, écrire directement StaticModule, et en dériver BattleModule tout en en surchargeant les méthodes ? Quest-ce que je pourrais y gagner ou y perdre ?
C’est une très mauvaise idée comme l’a fait remarquer Souane, la relation d’héritage doit vraiment correspondre avec la notion que la sous-classe est une classe mère spécialisée. Est-ce que tu estimes qu’un BattleModule est un StaticModule ? Est-ce que tu estimes qu’un BattleModule est un Module ? Ce moyen simple permet d’éviter de mal employer l’héritage, et donc d’éviter les inconvénients présentés par Souane.