|
SEB |
Posté le 03 Août 2010 à 19:16 |

Messages : 554
|
Oui je pense ce choix est plus adapté et je suis sur que de ne pas faire d'héritage multiple t'évitera de grands maux de tête et des plantages plus que douteux.
|
|
freemaul |
Posté le 03 Août 2010 à 11:54 |

Messages : 174
|
En fait je dérivais DessinableSFML de sf::Drawable pour que les autres classes ait accès aux méthodes de sf::Drawable.
Mais en y réfléchissant cela fait que je ne devient plus totalement indépendant du moteur graphique choisit.
Par ailleurs je m'était dit "se serait bien de pouvoir dérivée de tout les sf::Drawable définit dans la sfml" mais la aussi, si je n'utilise plus la SFML ca ne fonctionne plus.
Donc je pense plutôt faire des SpriteSFML, FormeSFML, ... (qui dériveront de DessinableSfml<T> avec T comme membre privé) mais qui seront donc tous définit par moi même dans le moteur. Et l'utilisateur n'auras jamais à utiliser directement un DessinableSfml.
Merci de m'avoir éclairé, je pense que mon choix est fait maintenant.
|
|
SEB |
Posté le 02 Août 2010 à 15:08 |

Messages : 554
|
Hello, oui j'ai bien compris ce que tu veux faire, et justement ce que je vois c'est que la réponse n'est pas vraiment vraiment OUI à la troisième question.
Je m'explique : la question est "Est-ce réellement pour spécialiser a la fois des dessinable et des sf:Drawable ?". Mais la ou je me suis mal exprimé, c'est que je sous entendais une spécialisation de 'comportement' pour chacune des classe parente. Je vois bien que c'est une spécialisation des deux, mais ma question portait plus sur le fait de spécialiser les comportement. Mais un exemple sera sans doute plus clair.
Admettons que la classe Dessinable ait donc une methode Dessine.
Code : C++
class Dessinable {
public:
// constructeur
Dessinable() ;
// methode virtuelle de dessin
virtual void Dessine() ;
};
Notre souhait est que l'on puisse utiliser des dérivées de dessinables, mais également que ces mêmes dérivées puissent etre indépendante du moteur cible (SFML, SDL ou autre)
En gros comme tu le disais on voudrait pouvoir déclarer facilement les classes suivantes :
Code : C++
class DessinableSFML : Dessinable, sf::Drawable {
public:
void Dessine() {
Draw(); // redirige vers la maniere sfml
}
};
class DessinableSDL : Dessinable, trucSDL {
public:
void Dessine() {
DrawTrucSdl();
}
};
Sauf que le template nous permettrai de facon simple, de déclarer toutes les spécialisations que l'on veut.
Si l'objectif est celui la, cet héritage multiple n'est pas utile.
Si par contre la classe sf::Drawable avait par exemple une methode Update() dont nous voudrions changer le comportement en meme temps, la ce template peut (éventuellement) s'accepter.
Exemple :
Code : C++
class Dessinable {
public:
// constructeur
Dessinable() ;
// methode virtuelle de dessin
virtual void Dessine() ;
};
namespace sf {
class Drawable {
public:
// constructeur
Drawable() ;
// methode virtuelle de dessin
virtual void Update() ;
};
}
class DessinableSFML : Dessinable, sf::Drawable {
public:
void Update() {
// effectue des operations specifiques
}
void Dessine() {
Draw(); // redirige vers la maniere sfml
}
};
class DessinableSDL : Dessinable, trucSDL {
public:
void UpdateSdl() {
// effectue des operations specifiques
}
void Dessine() {
DrawTrucSdl();
}
};
Dans le cas ou l'on ne souhaite pas volontairement dériver des fonctions SFML ou SDL, a mon sens il serait largement préférable d'utiliser également un template mais pas pour dériver, pour conserver un pointeur. Donc je transformerais simplement ton code de la maniere suivante :
Code : C++
template<class T>
class DessinableSfml : public MoteurGClasses::Dessinable {
public:
DessinableSfml();
void Cache();
void Montre();
void Dessine(MoteurG* mg) {
_engineElement->Draw();
}
void Positionne(float x,float y);
protected:
///\\brief pointeur vers l'element specifique du moteur cible
T* _engineElement;
///\\brief Bool actif si Dessinable doit être dessine
bool montre;
};
Voila j'espère que mes explications ne sont pas trop embrouillées.
|
|
freemaul |
Posté le 31 Juil 2010 à 15:55 |

Messages : 174
|
C'est plutôt oui à la 3ème question. Et effectivement tu a bien compris ce que je veux faire. Mais je vais essayer de l'expliciter un peu mieux.
Je veux faire un moteur de jeu qui puisse utiliser différente librairie graphique (que SFML pour le moment, mais j'aimerais qu'un changement vers SDL ou autre soit facil), J'ai donc une classe abstraite Dessinable avec une fonction Dessiner qui sera donc appelée par mon moteur de jeu.
Dans SFML tout ce qui est affichable est dérivé de sf::Drawable qui contient la fonction Draw().
Dans un premier temps je m'étais dit :
Je créé une classe DessinableSFML qui dérive de sf::Drawable et de Dessinable. Je définit la fonction Dessiner() qui appelle donc la fonction Draw() de sf::Drawable. Ors si je veut par exemple afficher un sf::Sprite je doit donc créer une classe qui dérive de sf::Sprite et de DessinableSFML, mais forcément il y a un problème d'héritage multiple de sf::Drawable.
Donc je me suis dit ensuite que je pouvais utiliser les template, la classe DessinableSFML dériverais donc de Dessinable et de T. Et la fonction Dessiner() apelle la fonction Draw() de T. Ainsi un sprite serait donc un objet DessinableSFML avec comme template sf::Sprite. Ca marche très bien, mais pas moyen de dire au compilo "je veux que T soit un sf::Drawable".
La seule solution trouvée par Darktib : Comme Dessiner() appelle T::Draw() le compilateur refusera de compiler si T ne contient pas Draw(), mais si T contient une fonction Draw() sans pour autant être dérivée de sf::Drawable cela compile quand même.
Solution pas encore testée : appeller dans Dessiner la fonction ((sf::Drawable)T)::Draw() ??
Voila, j'espère que tu vois mieux pourquoi je veux faire ça, et si tu a une autre idée d'implémentation je suis tout à fait ouvert.
|
|
SEB |
Posté le 31 Juil 2010 à 09:17 |

Messages : 554
|
Honettement je n'avais jamais eu cette idée mais c'est vrai que ca pourrait être sympa à priori.
Cependant cela me pose plusieur problemes...
1 Est-ce que ce genre de classe compile sous l'ensemble des compilos ???
2 Attention... attention... a l'héritage multiple. C'est une source de pièges et de bug assez importante et donc une manière de procéder plutôt risquée si on est pas sur à 100% de ce que l'on fait.
3 Quel est l'objectif final de cette technique? parceque la je ne vois pas quel problème ce type d'approche peut résoudre.
Je pense que ton explication était la pour le dire mais j'avoue que je ne comprend pas tout encore. Je vois que l'objectif est en gros de permettre que l'objet soit manipulé par la Sfml mais également manipulé en tant qu'objet dessinable apartenant à un moteur autre.
En gros il peut etre utilise normalement par la sfml mais également par ce moteur. J'imagine donc que ce moteur contient un ensemble de Dessinable* et la Sfml doit en gros se débrouiller avec ses dérivées de sf::Drawable. Et donc pour simplifier le tout (a priori) l'idéal ici est de créer une classe qui soit donc a la fois un Dessinable et un sf::Drawable.
Les questions a se poser sont donc les suivante :
- Est-ce juste parce-que cela parait plus joli a la conception ?
- Est-ce pour une commodité de manipulation et d'accès (apparente) ?
- Est-ce réellement pour spécialiser a la fois des dessinable et des sf:Drawable ?
Je dirai a priori que ce template pourrait (éventuellement) être utile uniquement si la réponse est oui à la troisième question.
Si la réponse est non a chacune des question... je pense qu'il n'y aurait meme pas de sujet.
Si la réponse est oui à la première, dans ce cas il serait peut etre bon de nous en dire un peu plus pour voir quelle serait la meilleure optique.
Si la réponse est oui à la seconde, il serait peut-etre plus intéressant de songer à conserver des références d'un objet a l'autre plutôt qu'un héritage multiple.
|
|
freemaul |
Posté le 27 Juil 2010 à 08:32 |

Messages : 174
|
C'est finalement ce que j'ai fait oui, et puis remplacer T par SFDRAWABLE pour que se soit bien explicite pour le programmeur qu'il faut que se soit un sf::Drawable ou dérivé.
|
|
Darktib |
Posté le 26 Juil 2010 à 19:20 |

Messages : 4017
|
Avec les templates, je pense que c'est faisable avec Boost, mais c'est très lourd.
Sinon, tu peux toujours essayer de créer une fonction utilisant une méthode de SFML::Drawable, du coup à la compilation si T ne dérive pas de SFML::Drawable et il y a de fortes chances que la méthode appellée n'existe pas, et donc que ca ne compile pas.
|
|
freemaul |
Posté le 25 Juil 2010 à 12:30 |

Messages : 174
|
Bonjour,
savez vous si il y a possibilité lorsque je créé une classe template, de forcer à ce que ce template soit dérivée d'une certaine classe ?
Ce n'est pas très claire je sais, donc en gros ce que je veux faire :
Code :
template<class T>
class DessinableSfml : public MoteurGClasses::Dessinable,public T
{
public:
DessinableSfml();
void Cache();
void Montre();
void Dessine(MoteurG* mg);
void Positionne(float x,float y);
protected:
///\\brief Bool actif si Dessinable doit être dessine
bool montre;
};
La classe DessinableSfml est dérivée d'une classe abstraite Dessinable, et d'une autre classe T
Je veut pouvoir utiliser DessinableSfml avec toutes les dérivée de sf::Drawable (venant de la SFML).
Là ca marche trés bien, mais je voudrais limiter l'utilisation de cette classe aux classes Sfml, donc en gros dire explicitement que dans "template<class T>" T est forcément dérivé de sf::Drawable.
Une idée ?
|