CONNEXION
  • RetourJeux
    • Sorties
    • Hit Parade
    • Les + populaires
    • Les + attendus
    • Soluces
    • Tous les Jeux
    • Gaming
  • RetourActu Gaming
    • News
    • Astuces
    • Tests
    • Previews
    • Toute l'actu gaming
  • RetourBons plans
    • Bons plans
    • Bons plans Smartphone
    • Bons plans Hardware
    • Bons plans Image et Son
    • Bons plans Amazon
    • Bons plans Cdiscount
    • Bons plans Decathlon
    • Bons plans Fnac
    • Tous les Bons plans
  • RetourJVTech
    • Actus High-Tech
    • Intelligence Artificielle
    • Smartphones
    • Mobilité urbaine
    • Hardware
    • Image et son
    • Tutoriels
    • Tests produits High-Tech
    • Guides d'achat High-Tech
    • JVTech
  • RetourCulture
    • Actus Culture
    • Culture
  • RetourVidéos
    • A la une
    • Gaming Live
    • Vidéos Tests
    • Vidéos Previews
    • Gameplay
    • Trailers
    • Chroniques
    • Replay Web TV
    • Toutes les vidéos
  • RetourForums
    • Hardware PC
    • PS5
    • Switch 2
    • Xbox Series
    • Switch
    • Pokemon pocket
    • FC 25 Ultimate Team
    • League of Legends
    • Tous les Forums
  • PC
  • PS5
  • Xbox Series
  • Switch 2
  • PS4
  • One
  • Switch
  • iOS
  • Android
  • MMO
  • RPG
  • FPS
En ce moment Genshin Impact Valhalla Breath of the wild Animal Crossing GTA 5 Red dead 2
Liste des sujets

[C++] Collection hétérogène

Caudheur
Caudheur
Niveau 8
20 octobre 2012 à 11:30:02

Salut à tous,

J'ai un problème dont j'aimerais me sortir de façon la plus élégante possible (faire du joli code quoi :content: )

J'ai une classe "A", qui est une classe mère qui sert d'interface pour deux autres classes : "B" et "C". Ainsi, toutes deux héritent de "A" et redéfinissent ses fonctions virtuelles.

J'ai besoin d'utiliser une collection hétérogène de type "A", qui contient donc un objet de classe "B" et un objet de classe "C".

Ma question est la suivante : comment faire une résolution de lien pour que je puisse obtenir les classes filles ("B" ou "C") depuis la collection de type mère ("A") ?

Pour être plus concret : comment puis-je avoir un getter du genre :

A *tab[2];
tab[0] = new B();
tab[1] = new C();

B &get_B()
{
return *tab[0];
}

Merci d'avance !

hyrulink2
hyrulink2
Niveau 7
20 octobre 2012 à 11:49:48

As-tu vraiment besoin de faire ça? Généralement le fait de vouloir obtenir le type de base d'une classe polymorphe est un signe de mauvais design.

Réfléchis bien à ce que tu veux faire, explique plus précisément ton problème. Il existe un moyen de faire ce que tu veux(dynamic_cast) mais ce n'est pas très propre.

Pour gérer une collection hétérogène on utilise plutôt des méthodes virtuelles, on a pas à s'occuper du type des objets de la liste.

Caudheur
Caudheur
Niveau 8
20 octobre 2012 à 12:46:44

En effet, je me suis dit que la conception pouvait être défaillante (puisque utiliser une collection c'est justement réunir les objets).

Pour être tout a fait concret, j'ai une classe-interface "Scene", et des classes filles "Scene_titre" et "Scene_principale".

Les objets de types "Scene" partagent des méthodes comme "dessiner()", ou "update()".

Cependant, la "Scene_titre" par exemple a une méthode qui lui est spécifique, comme "commencer_partie()".

Du coup je ne sais pas trop comment concevoir tout ça proprement !

lokilok
lokilok
Niveau 17
20 octobre 2012 à 13:03:47

Personnellement j'aurais utilisé les unions mais après si c'est propre ou pas ça je sais pas...

Caudheur
Caudheur
Niveau 8
20 octobre 2012 à 13:16:58

Peux tu m'en dire plus, je ne connais pas ce terme :)

hyrulink2
hyrulink2
Niveau 7
20 octobre 2012 à 13:42:25

Si je comprends bien tu as plusieurs scènes qui s’emboîtent?

Tu ne peux pas faire une méthode virtuelle start() qui contient la logique de commencement de la scène qui appellerai commencer_ partie dans le cas de Scene_titre?

lokilok
lokilok
Niveau 17
20 octobre 2012 à 13:49:00

http://cpp.developpez.com/cours/cpp/?page=page_5#LV-A-2

En gros ta classe A aura une union contenant un pointeur sur une classe B et un autre sur une classe C, t'auras juste à initialiser tout ça dans le constructeur en rajouter une variable à A qui indiquera son type (si c'est B ou C quoi).

Après comme j'ai dis j'en sais rien si c'est propre ou pas, mais c'est une solution possible.

Caudheur
Caudheur
Niveau 8
20 octobre 2012 à 14:04:36

@ hyrulink2 : J'y ai pensé, mais du coup la classe mère "Scene" devra avoir toutes les méthodes spécifiques des scenes filles !
En fait je m'aperçois que les classes interfaces doivent être utilisées avec parcimonie : ce sont vraiment des cas particuliers.

@ LOKILOK : merci pour le lien, je ne connaissais pas du tout cet usage des structures !
Je vais étudier ça.

En tout cas merci à vous :)

chris_27
chris_27
Niveau 10
20 octobre 2012 à 20:22:55

La réponse à la question initiale est TRÈS simple : "pas./"

Normalement, une fois que tu as mis ensemble des torchons (B) et des serviettes (C), tu ne fais plus que des traitements qui ont un sens pour les torchons et les serviettes (appeler la méthode essuyer par exemple). Bien sur, le code qui sera utilisé va dépendre du type réel de ton objet, mais ceci est fait pour toi à l'éxecution, sans que tu ais besoin de savoir dans quel cas (B ou C) tu te trouves.

« Cependant, la "Scene_titre" par exemple a une méthode qui lui est spécifique, comme "commencer_partie()". » :d) vu de loin, j'ai envie de dire que ce n'est pas à un écran de commencer la partie. Après, c'est très facile de dire ça... je n'ai pas l'organisation globale sous les yeux, ni les sémantiques des classes Screen_foo et de la méthode commencer_partie().
Cela dit, assure toi que le code de cette méthode est bel et bien à sa place. :-)

LOKILOK :
« Après comme j'ai dis j'en sais rien si c'est propre ou pas, mais c'est une solution possible. » :d) ça se situe quelque part entre "dégueulasse" et "pire". :(

En vrai, les unions c'est l'horreur. Le seul cas propre que j'ai en tête, c'est quand on veut manipuler la structure interne d'un nombre flottant. Mais pratiquement personne ne fait des choses aussi bas niveau (hors gens qui codent une libm).

godrik
godrik
Niveau 30
20 octobre 2012 à 20:25:09

Je fais de l'union parfois, mais c'est toujours pour des raisons obscure et inavouable. Tiens toi le plus loin de union que possible. C'est bon pour ta sante mentale!

Caudheur
Caudheur
Niveau 8
20 octobre 2012 à 22:42:53

Haha, merci à vous deux ! J'éviterai donc les union.

Du coup j'ai revu le design général, qui est maintenant plus propre et évite l'usage peu justifié que je faisais des collections hétérogènes.
C'est interessant que ce soit un point technique qui force le programmeur à revoir toute la structure de son programme. Ça doit faire partie de ce qui fait que j'aime le C++ :(

chris_27
chris_27
Niveau 10
20 octobre 2012 à 23:57:27

Vu autrement, c'est parce que tu voulais faire l'impossible (ou presque) que la technique ne suit pas. :-)))

Ce que tu appelles "collection hétérogène" a pour principal intérêt de masquer l'hétérogénéité justement. À partir de là, on sent bien que discriminer dans la collection en fonction du type c'est aller contre nature. :(

Sous forums
  • Aide à l'achat Mac
  • Macintosh
  • Création de Jeux
  • Programmation
  • Création de sites web
  • Linux
  • Internet
  • Steam Deck
  • Hardware
La vidéo du moment