OVH Cloud OVH Cloud

Héritage ou dll ?

24 réponses
Avatar
Spoofix
Bonjour,

Je voudrais commencer à écrire un moteur 3D, mais pour lequel ou pourrait
choisir entre OpenGL et DirectX. En fait, mon probleme C++ est le suivant :
certaines fonctions seront écrites 2x : une fois pour OpenGL et une fois
pour DirectX. Je voudrais avoir qu'un seul nom de fonction pour ces 2
fonctions.
J'ai pensé à 2 solutions :

1. Avoir 2 dll séparées, contenant les fonctions concernées, et charger
dynamiquement la bonne au démarrage. Est-ce possible (je n'ai encore jamais
programmé de dll) ?

2. Avoir une classe mère CMaClasse avec des fonctions membres virtuelles (ex
: virtual MaFonction()=0 ). Puis créer 2 classe filles : CMaClasse_gl et
CMaClasse_dx. Et faire :

CMaClasse *Objet;
if (OpenGL)
Objet = new CMaClass_gl;
else
Objet = new CMaClass_dx;

Qu'en pensez vous ? Avez d'autres solutions ? Sachant que je recherche la
méthode la plus rapide...

Merci d'avance.
Clément.

4 réponses

1 2 3
Avatar
kanze
Vincent Richard wrote
in message news:<3fa16017$0$27021$...

Je voudrais commencer à écrire un moteur 3D, mais pour lequel ou
pourrait choisir entre OpenGL et DirectX. En fait, mon probleme C++
est le suivant : certaines fonctions seront écrites 2x : une fois
pour OpenGL et une fois pour DirectX. Je voudrais avoir qu'un seul
nom de fonction pour ces 2 fonctions.
J'ai pensé à 2 solutions :
1. Avoir 2 dll séparées,


Les DLL c'est HS ici.


Oui et non. Les détails de l'API, oui. Les considérations générales, en
revanche, pas vraiment.

Je vais donc te donner une "solution C++".

2. Avoir une classe mère CMaClasse avec des fonctions membres
virtuelles
CMaClasse *Objet;
if (OpenGL)
Objet = new CMaClass_gl;
else
Objet = new CMaClass_dx;

Qu'en pensez vous ? Avez d'autres solutions ? Sachant que je
recherche la méthode la plus rapide...


Au passage, tester à chaque création d'objet si on est en mode DX ou
OpenGL n'est pas très performant (ni très lisible, d'ailleurs).

Je te propose de faire une hiérarchie de classes abstraites :

Moteur <-- contiennent des fonctions virtuelles pures _uniquement_
Objet
Scene
...

et de classes concrètes :

MoteurDX et MoteurOGL <-- contiennent l'implémentation
ObjetDX et ObjetOGL
SceneDX et SceneOGL
...

et de créer des fabriques abstraites et concrètes :

FabriqueMoteur (abstraite) et FabriqueMoteurDX, FabriqueMoteurOGL
FabriqueObjet et FabriqueObjetDX, FabriqueObjetOGL


Je verrais plutôt une seule fabrique, avec des fonctions virtuelles
distinctes pour chaque type d'objet.

Ensuite, au niveau de l'utilisation :

// Instanciation d'un moteur
Moteur* m = FabriqueMoteur::instance().create("OpenGL");

// Instanciation d'une scène
Scene* s = m->fabriqueScene().create();

// Instanciation d'objets
Objet* o1 = s->fabriqueObjet().create();
Objet* o2 = s->fabriqueObjet().create();

ce qui fait qu'on ne travaille qu'avec des objets "abstraits".


Je ne suis pas sûr d'avoir compris ce que tu veux faire.

Comme j'ai dit, je verrais une seule fabrique, avec une variation sur le
singleton. Grosso modo :

class GUIFactory
{
public:
static void initialize( char const* libraryName ) ;
static GUIFactory& instance() ;

virtual Moteur* createMoteur() const = 0 ;
virtual Objet* createObjet() const = 0 ;
// ...

private:
static GUIFactory* ourInstance ;
} ;

GUIFactory&
GUIFactory::instance()
{
assert( ourInstance != NULL ) ;
return *ourInstance ;
}

void
GUIFactory::initialize( char const* libraryName )
{
assert( ourInstance == NULL ) ;
// Charger le DLL qui correspond...
// Créer l'instance de la fabrique qui correspond...
ourInstance = cetteInstance ;
}

Dans les DLL, il suffit d'exporter une seule fonction globale
createGUIFactory, qui renvoie un GUIFactory* qui point en fait à une
fabrique du bon type.

En principe, on pourrait utiliser le même nom de classe dans les deux
cas -- il y aurait deux DLL distincts, une par classe, et on chargerait
jamais les deux à la fois. Mais dans la pratique, je crois que la
maintenance du code serait bien plus simple avec des noms différents.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16


Avatar
Christophe Lephay
wrote:
Vincent Richard wrote
MoteurDX et MoteurOGL <-- contiennent l'implémentation
ObjetDX et ObjetOGL
SceneDX et SceneOGL
...

et de créer des fabriques abstraites et concrètes :

FabriqueMoteur (abstraite) et FabriqueMoteurDX, FabriqueMoteurOGL
FabriqueObjet et FabriqueObjetDX, FabriqueObjetOGL


Je verrais plutôt une seule fabrique, avec des fonctions virtuelles
distinctes pour chaque type d'objet.


Comme je l'ai écrit dans un autre post, le fait d'avoir plus de fabrique
permet un niveau plus complexe de paramètrage, par exemple on n'utiliserait
pas la même fabrique pour faire des objets DirectX selon la définition, le
nombre de couleurs, ou même les performances de la machine hôte...

Après, bien entendu, l'évolutivité a un coût, et ce n'est qu'au cas par cas
qu'on peut décider si ce coût est justifié ou non. Cependant, il me semble
que le coût engendré par un niveau d'indirection supplémentaire (une
fabrique en plus) est assez minime 1- parce que ce n'est pas trop complexe à
implémenter et 2- vu le caractère assez idiomatique et, à ce titre,
"auto-documentaire" d'une fabrique.

Chris


Avatar
kanze
"Christophe Lephay" wrote in message
news:<bo835q$dkm$...
wrote:
Vincent Richard wrote
MoteurDX et MoteurOGL <-- contiennent l'implémentation
ObjetDX et ObjetOGL
SceneDX et SceneOGL
...

et de créer des fabriques abstraites et concrètes :

FabriqueMoteur (abstraite) et FabriqueMoteurDX, FabriqueMoteurOGL
FabriqueObjet et FabriqueObjetDX, FabriqueObjetOGL


Je verrais plutôt une seule fabrique, avec des fonctions virtuelles
distinctes pour chaque type d'objet.


Comme je l'ai écrit dans un autre post, le fait d'avoir plus de fabrique
permet un niveau plus complexe de paramètrage, par exemple on n'utiliserait
pas la même fabrique pour faire des objets DirectX selon la définition, le
nombre de couleurs, ou même les performances de la machine hôte...

Après, bien entendu, l'évolutivité a un coût, et ce n'est qu'au cas
par cas qu'on peut décider si ce coût est justifié ou non. Cependant,
il me semble que le coût engendré par un niveau d'indirection
supplémentaire (une fabrique en plus) est assez minime 1- parce que ce
n'est pas trop complexe à implémenter et 2- vu le caractère assez
idiomatique et, à ce titre, "auto-documentaire" d'une fabrique.


Si j'ai bien compris ce que tu proposes, c'est un éspèce de fabrique des
fabriques -- vue la complexité des hièrarchies en question, ça pourrait
éventuellement être une bonne idée. Encore que quand je l'ai fait...

Ce que je voulais montrer en plus, c'était aussi la façon qu'on
utilisait une fabrique singleton pour encapsuler d'une façon simple et
élégante l'utilisation des DLL's diverses. L'une n'exclut pas l'autre.

--
James Kanze GABI Software mailto:
Conseils en informatique orientée objet/ http://www.gabi-soft.fr
Beratung in objektorientierter Datenverarbeitung
11 rue de Rambouillet, 78460 Chevreuse, France, +33 (0)1 30 23 45 16



Avatar
Christophe Lephay
wrote:
"Christophe Lephay" wrote in message
news:<bo835q$dkm$...
Comme je l'ai écrit dans un autre post, le fait d'avoir plus de
fabrique permet un niveau plus complexe de paramètrage, par exemple
on n'utiliserait pas la même fabrique pour faire des objets DirectX
selon la définition, le nombre de couleurs, ou même les performances
de la machine hôte...


Si j'ai bien compris ce que tu proposes, c'est un éspèce de fabrique
des fabriques -- vue la complexité des hièrarchies en question, ça
pourrait éventuellement être une bonne idée. Encore que quand je l'ai
fait...


En fait, j'argumente pour la proposition de quelqu'un d'autre : c'est
Vincent (ou Richard ?), je crois, qui a suggéré une telle hiérarchie.
Quoiqu'il en soit, c'est bien d'une fabrique de fabriques dont il est
question, bien que celà ne m'apparaisse que maintenant que tu l'as dit :-)

Chris


1 2 3