120

Je ne sais pas si c'était bien ou mal, mais en Java, j'ai déjà utilisé pas mal "instanceof" pour traiter, suivant le type des éléments, des arbres abstraits de syntaxe. C'était clairement le plus pratique à écrire.
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

121

avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

122

Sasume (./119) :
Pensez-vous qu’utiliser instanceof est mal ?

Oui et non... il y a par exemple des situations où c'est indispensable parce qu'on ne peut pas savoir à l'avance quel objet on va manipuler (si l'objet créé l'est pas une action de l'utilisateur, et que l'utilisateur peut créer des objets suffisamment différents pour qu'on ne puisse pas les gérer de façon identique). Cela dit, si on doit vraiment pouvoir faire des tests sur la nature de l'objet avant d'exécuter une action, il est peut-être plus propre d'avoir des objets ayant alors une méthode getType() qui retourne le type d'objet dans son sens métier et dans dans sa dénomination interne propre au développement.
avatar

123

Kevin Kofler (./116) :
Il y a 15408 lignes de code dans KTIGCC 1 et 17184 dans KTIGCC 2 (et je n'ai pas compté les sorties de uic et moc là).


Au boulot, on doit avoir le même nombre de lignes dans un seul fichier cheeky
avatar
Appartiens à l'Unification Ultime !

Exec "4e444e750000"

124

./121: oui, c'était du Visitor, en effet.
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

125

Ben justement Visitor te permet de ne pas avoir à utiliser instanceof (enfin, il fait juste faire un gros détour, mais le résultat est le même, modulo le fait que c’est plus sûr).
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

126

pour éviter instanceof on peut aussi avoir un champ type dans la super classe et faire des casts...

127

Bof, ça revient exactement au même, en plus lourd et moins bien.
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

128

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.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

130

Bon, pour revenir sur les héritages & co, j'ai deux questions tout à fait distinctes, une purement conceptuelle, l'autre se rapprochant de l'implémentation.

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


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





En fait, on pourrait considérer que mon programme est un objet et main son constructeur, qui s'occupe de la SDL pour fournir au Task Manager l'interface qu'il lui faut pour faire travailler ses modules. Comme ça c'est du pur objet. ^^

131

2. Le principe a priori, pour te simplifier le travail, c'est que tu mutualises tout ce qui peut être mutualisé dans la superclasse abstraite Module. Que ce soient des variables, des implémentations de méthodes, des méthodes abstraites, etc... (note qu'en Java il y a un moyen d'empêcher que des méthodes non abstraites de la superclasse soient réécrites par l'une des classes filles : ajouter le mot "final"). Donc, personnellement, si je sais qu'une méthode (y compris le constructeur) est exactement la même dans toutes les sous-classes, j'aurais tendance à l'implémenter dans la classe mère pour éviter des inconsistances si je fais des copier-coller dans les classes filles (on peut oublier de copier des changements apportés à la même méthode dans toutes les sous-classes concernées, par exemple, ce qui n'est pas chouette happy)
avatar
I wanna... bioman, bioman, défenseur de la teeeerrrreee

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 ?

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 ?

133

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 ?

Question intéressante. Je dirais que le cas évident, c'est si les méthodes sont vraiment totalement différentes d'une fille à une autre => méthode abstraite
Dans les autres cas il faut sans doute que tu regardes ce qui est mieux au cas par cas et là je ne sais pas s'il y a une réponse toute faite happy

Folco (./132) :
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 ?

J'aurais tendance à dire que c'est le Mal absolu embarrassed (sans déconner hein). Déjà ce sera le gros bordel, car static module et battle module n'ont quand même pas grand chose à voir, et ensuite tu pourrais oublier de réécrire une méthode et t'aurais des mauvaises surprises. Et puis sinon, ou c'est en tout cas ce que j'ai compris, tu n'es pas censé créer de l'héritage parce que ça t'arrange (cf. points précédents et sans doute d'autres), mais c'est censé correspondre à une réalité. Or, un battle module n'est pas un type de static module mais un type de module... Si tu tiens vraiment à réécrire toutes les méthodes présente dans StaticModule, il te suffit de les définir dans Module et de ne pas les implémenter du tout... ça demande pas beaucoup de travail et c'est juste plus propre smile
avatar
I wanna... bioman, bioman, défenseur de la teeeerrrreee

134

Souane (./133) :
J'aurais tendance à dire que c'est le Mal absolu redface.gif (sans déconner hein). Déjà ce sera le gros bordel, car static module et battle module n'ont quand même pas grand chose à voir, et ensuite tu pourrais oublier de réécrire une méthode et t'aurais des mauvaises surprises. Et puis sinon, ou c'est en tout cas ce que j'ai compris, tu n'es pas censé créer de l'héritage parce que ça t'arrange (cf. points précédents et sans doute d'autres), mais c'est censé correspondre à une réalité. Or, un battle module n'est pas un type de static module mais un type de module... Si tu tiens vraiment à réécrire toutes les méthodes présente dans StaticModule, il te suffit de les définir dans Module et de ne pas les implémenter du tout... ça demande pas beaucoup de travail et c'est juste plus propre smile.gif

Ok. Merci bien, et oui ça me semble pas très propre, voire même franchement hideux mon idée. grin Et en effet ça ne correspond à rien dans la réalité.

ps à tous -> je suis encore preneur de réponses pour le reste de mon ./130, j'arrive pas à trouver de solution intelligente cheeky

135

On voit des héritages comme ça de temps en temps, effectivement ça donne à vomir, et ça suscite des réactions comme "Hein??? Chien dérive de Chat???" gni
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

136

c'est ce qui finit par arriver dans les projets open source ou on designe en même temps qu'on code, au lieu d'avoir un document de design sur lequel se baser avant de coder...
kevin, ce post est de l'humour, il ne faut pas y répondre sérieusement... si tu l'avais vu tant mieux, sinon ne te mets pas la rate au court bouillon pour ça smile

137

(et euh... si j'avais mes réponses avant que vous continuiez dans l'humour ça serait cool, juste histoire que mes posts ne soient pas perdu dans la masse, merci d'avance happy)

138

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.
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

139

Ce qui est rigolo c'est que j'arrive à coder des design patterns sans le savoir triso

dans une appli j'ai implémenté le pattern Commande sus-cité sans savoir que ça existait grin

140

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.

À mon avis, il faudrait passer le pointeur vers le gestionnaire de tâches dans le constructeur de chaque classe, ou le lui faire récupérer automatiquement à partir de la classe parent qu'on lui passe.

Sinon il y a aussi le singleton comme solution, ou alors tu fais carrément du gestionnaire de tâches un module (un .cpp avec des fonctions procédurales) plutôt qu'un objet. Le singleton est la version "pur objet" du module.
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 ?

C'est un peu le but de protected. smile

Cela dit, si tu veux encapsuler très fortement ta classe (genre si tu veux permettre des classes dérivées par autrui que toi et que tu veux éviter que tes changements cassent leur code), tu mets tes membres en private, des accesseurs pour les classes dérivées (pour ce pour quoi il n'y a pas d'accesseur public) en protected et les accesseurs publics en public.

(Et attention, quand je dis "accesseur", ce n'est pas forcément un bête get/set, ça peut aussi être une interface spécialisée qui abstrait entièrement les membres.)

J'ai bien compris la POO, je n'ai juste pas l'habitude de l'utiliser. tongue
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

Si tu veux permettre aux classes dérivées de surcharger ta méthode, tu as tout intérêt à la rendre virtual, sinon tu risques de mauvaises surprises! Mais si surcharger la méthode n'a aucun sens, il vaut mieux éviter le virtual, à la fois pour la performance et parce que la compatibilité antérieure binaire est plus simple à réaliser avec des méthodes non-virtuelles (cf. http://techbase.kde.org/Policies/Binary_Compatibility_Issues_With_C++ si tu as envie de savoir tout sur la compatibilité binaire, c'est vraiment le bordel).
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

141

Merci beaucoup pour toutes vos explications, votre temps et votre patience ! smile

142

Pas de problème ! Cette discussion est vraiment très intéressante et tu n'es pas le seul à en apprendre happy
avatar
I wanna... bioman, bioman, défenseur de la teeeerrrreee

143

Sasume (./138) :
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.

C'est du bidouillage, tout ça. En fait, le concept que tu cherches, c'est http://doc.qt.nokia.com/4.7-snapshot/signalsandslots.html. smile

Et sinon, en C++, on utilise normalement operator() plutôt que execute. smile
(vu qu’en C++ on ne peux pas écrire de classes anonymes…)

Euh si, on peut:
class {
  …
} x;


Et on peut aussi coller plusieurs classes non-anonymes dans le même .cpp.
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)

… ou celui de Qt. tongue

Il y a aussi la libQtCore, hein, on peut utiliser le C++ amélioré de Qt même sans avoir une interface graphique en Qt.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

144

Kevin Kofler (./140) :
À mon avis, il faudrait passer le pointeur vers le gestionnaire de tâches dans le constructeur de chaque classe

J'ai commencé à implanter qqchose : passer un pointeur vers un objet Message dans le constructeur de chaque classe en effet. Cet objet est créé en une instance unique par le gestionnaire de modules.

Et sinon, j'ai réalisé aussi qu'un module peut demander à se décharger/ en charger un autre, ou alors à en charger un autre par-dessus lui (par exemple quand on va afficher les propriétés d'une unité sur le champs de bataille, on va faire "afficher un objet StaticModule" sur le BattleModule. Donc il faut que mon manageur retienne l'est pointeurs de tous ces modules. Donc il faut qu'il utilise un tableau dynamique.
Je n'ai pas encie d'utiliser la STL et ses conteneurs, et je n'ai pas trouvé de "realloc" qui serait à new/delete ce que realloc est à malloc/free... Je vais donc faire une classe tableau avec quelques méthodes... A moins que j'ai loupé un truc ou que ce soit pas bien de procéder ainsi ?

145

Le problème, c'est que realloc peut être problématique pour les classes non-POD. Tu peux travailler avec des tableaux de pointeurs, pour lesquels il est sans danger d'utiliser malloc/realloc/free comme en C.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

146

Kevin Kofler (./143) :
Et sinon, en C++, on utilise normalement operator() plutôt que execute. smile
Je suis assez réticent aux surcharges d’opérateurs. Quand on lit le code ensuite on ne sait pas ce qu’il fait : a + b peut très bien faire complètement autre chose qu’une addition, ça peut prêter à confusion. Cela dit l’opérateur () pose moins de problèmes.
(vu qu’en C++ on ne peux pas écrire de classes anonymes…)

Euh si, on peut:
class {
  …
} x;
Fonction(); } } monAction; Icon icon(monAction);
Ah ouais, du coup on peut faire un truc comme ça :class MonAction : public Action {
  public:
  void execute() {
    ma

Mais bon, c’est quand même moins lisible que les closures (et comment faire pour allouer avec l’opérateur new une classe anonyme ?), ou même que le code Java équivalent (uilisant une classe interne anonyme) :
Icon icon = new Icon(new Action() {
  public void execute() {
    maFonction();
  }
});

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)

… ou celui de Qt. tongue

Il y a aussi la libQtCore, hein, on peut utiliser le C++ amélioré de Qt même sans avoir une interface graphique en Qt.
roll Qt est très bien mais ça n’a aucun sens qu’il l’utilise dans ce projet, juste pour jouer avec les signals et les slots…
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

147

Sasume (./146) :
roll Qt est très bien mais ça n’a aucun sens qu’il l’utilise dans ce projet, juste pour jouer avec les signals et les slots…

Pourquoi pas? Perso, je code soit en C pur, soit en C++ avec Qt, même si c'est juste QtCore.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

148

Oui mais toi tu es parfait. Attention, 3e degré, je précise…
avatar
« Quand le dernier arbre sera abattu, la dernière rivière empoisonnée, le dernier poisson capturé, alors vous découvrirez que l'argent ne se mange pas. »

149

Kevin Kofler (./145) :
Le problème, c'est que realloc peut être problématique pour les classes non-POD. Tu peux travailler avec des tableaux de pointeurs, pour lesquels il est sans danger d'utiliser malloc/realloc/free comme en C.

Je vais avoir besoins de tableaux de pointeurs vers des objets. Et j'aime pas utiliser les fonctions C en C++, même si je sais que ça marche très bien, c'est comme ça. grin
Le but est justement de ne pas coder "à la C" (quoi déjà je fais pas ça bien ? oué je sais merci triso)

J'ai donc fait ma classe de conteneur :
class Container
{
    public:
        Container(int numElement, int sizeOf);
        ~Container();
        int resize();
        void deleteObjects();
        void *getPtr();
        int getNumElements();
        int getSizeOf();
    private:
        int m_NumElements;
        int m_SizeOf;
        void *m_Ptr;
};

J'avais regardé ceux de la STL, mais j'y avais rien compris grin

150

En ne pas utilisant les conteneurs de la STL tu rate un des plus grand avantages du C++ par rapport au C. Je dis ça, mais au début j'avais fait exactement la même chose que toi grin
Mais de toute façon à la longue tu en aura marre de recoder toujours la même chose, et donc tu finira par utiliser la STL smile