OVH Cloud OVH Cloud

Un problème...

40 réponses
Avatar
Zouplaz
Bonjour, je cherche à faire quelque chose mais j'ai du mal, je
m'explique.

Je voudrais qu'une classe de base baseObject implémente une méthode
statique createObject, méthode appellée en lieu et place de new lorsque
j'ai besoin de créer un objet.

Le problème c'est que je veux aussi créer des instances de classes
dérivées de baseObject. Et là ça coince, voici un extrait de mes
bidouilles :

----- BaseObject.h
public:
static BaseObject *createObject();

----- BaseObject.cpp
BaseObject *BaseObject::createObject()
{
BaseObject * newObj = new BaseObject();
newObj->ID = ++nextID;
return newObj;
}

----- WorldObject.h
class WorldObject : public BaseObject

----- Main.cpp
WorldObject* wo = (WorldObject *)BaseObject::createObject();

Le problème c'est que je suis obligé de faire un cast (forcément).
Non seulement c'est pas bien mais en plus la déclaration de fonctions
purement virtuellement dans WorldObject ne provoque pas d'erreur à la
compilation sur la ligne ci-dessus, donc c'est pire que pas bien.

L'idée d'avoir une sorte de mini-factory c'est de garder une trace des
objets qui ont été crées (en fait peut importe même, j'essaie de
comprendre).

Je pense que si j'utilisais un template je me sortirais de là, et
baseObject pourrait retourner le bon type.

Mais sans template ? Est-ce qu'il existe une solution ?

Merci de votre aide.

10 réponses

1 2 3 4
Avatar
Philippe Guglielmetti
WorldObject* wo = (WorldObject *)BaseObject::createObject();

Le problème c'est que je suis obligé de faire un cast (forcément).


oui, mais la manière C++ de faire est:
WorldObject* wo = dynamic_cast<WorldObject *>(BaseObject::createObject());
qui a l'intérêt de vérifier à l'exécution que le cast est légal

en plus la déclaration de fonctions
purement virtuellement dans WorldObject ne provoque pas d'erreur à la
compilation sur la ligne ci-dessus, donc c'est pire que pas bien.


non c'est très bien et très normal.

L'idée d'avoir une sorte de mini-factory c'est de garder une trace des
objets qui ont été crées (en fait peut importe même, j'essaie de
comprendre).


alors tu dois faire une factory qui prenne en paramètre le type de l'objet à
créer, du genre:

enum obj_type {base_type ,world_type };

BaseObject *BaseObject::createObject(const obj_type t)
{
BaseObject * ;
switch (t){
case base_type : newObj = new BaseObject(); break;
case world_type : newObj = new WorldObject(); break;
}
newObj->ID = ++nextID;
return newObj;
}

Je pense que si j'utilisais un template je me sortirais de là, et
baseObject pourrait retourner le bon type.


mauvaise idée, les termplates et le polymorphisme ne font pas bon ménage :
list<truc> et list<machin> n'ont aucun parent commun dans la hierarchie.

Si tu veux planer avec des factories générées automatiquement par des
templates, lis "Modern C++ Design" d'Alexandrescu.
Et puis relis-le.
Et puis lis le encore une fois.
Si t'as pigé après trois lectures, t'es un gourou C++
--
Philippe Guglielmetti - www.dynabits.com

Avatar
rlods
Zouplaz wrote in message news:...
Bonjour, je cherche à faire quelque chose mais j'ai du mal, je
m'explique.

Je voudrais qu'une classe de base baseObject implémente une méthode
statique createObject, méthode appellée en lieu et place de new lorsque
j'ai besoin de créer un objet.

Le problème c'est que je veux aussi créer des instances de classes
dérivées de baseObject. Et là ça coince, voici un extrait de mes
bidouilles :

----- BaseObject.h
public:
static BaseObject *createObject();

----- BaseObject.cpp
BaseObject *BaseObject::createObject()
{
BaseObject * newObj = new BaseObject();
newObj->ID = ++nextID;
return newObj;
}

----- WorldObject.h
class WorldObject : public BaseObject

----- Main.cpp
WorldObject* wo = (WorldObject *)BaseObject::createObject();

Le problème c'est que je suis obligé de faire un cast (forcément).
Non seulement c'est pas bien mais en plus la déclaration de fonctions
purement virtuellement dans WorldObject ne provoque pas d'erreur à la
compilation sur la ligne ci-dessus, donc c'est pire que pas bien.

L'idée d'avoir une sorte de mini-factory c'est de garder une trace des
objets qui ont été crées (en fait peut importe même, j'essaie de
comprendre).

Je pense que si j'utilisais un template je me sortirais de là, et
baseObject pourrait retourner le bon type.

Mais sans template ? Est-ce qu'il existe une solution ?

Merci de votre aide.


Une solution serait de creer ta methode statique factory dans toute
les classes derivees egalement (uniquement celles qui doivent pouvoir
etre instanciee).

Ton code si dessous est faux:
si WorldObject derive de BaseObject
et que BaseObject::createObject() instancie vraiment un BaseObject et
pas un WorldObject
alors il ne faut pas caster le retour de createObject en WorldObject.
c'est pas bien du tout.

Avatar
Zouplaz
theromulus - :

Une solution serait de creer ta methode statique factory dans toute
les classes derivees egalement (uniquement celles qui doivent pouvoir
etre instanciee).


Ha quand même je suis sceptique, tu te rends compte si j'ai 15 classes ?
Dupliquer 15 fois le même code juste pour une question de cast ? Ca me
semble pas trop logique...

Avatar
Zouplaz
Philippe Guglielmetti - :

Si tu veux planer avec des factories g‚n‚r‚es automatiquement par des
templates, lis "Modern C++ Design" d'Alexandrescu.
Et puis relis-le.
Et puis lis le encore une fois.
Si t'as pig‚ aprŠs trois lectures, t'es un gourou C++



Heu... J'ai déjà assez de mal avec l'aide en ligne (section C++, hein pour
pas être HS) de visual studio, alors le bouquin là... Même pas en rêve !

PS : Pourquoi tant de noms slaves dans le monde du C++ (cf le newsgroup
anglophone (pas mal de noms de cette origine), strouztruc, alexandrescu,
etc.))... Le C++ c'est un peu comme les échecs ?? Hein ?

Avatar
Loïc Joly
Zouplaz wrote:

Philippe Guglielmetti - :


Si tu veux planer avec des factories g‚n‚r‚es automatiquement par des
templates, lis "Modern C++ Design" d'Alexandrescu.
Et puis relis-le.
Et puis lis le encore une fois.
Si t'as pig‚ aprŠs trois lectures, t'es un gourou C++




Heu... J'ai déjà assez de mal avec l'aide en ligne (section C++, hein pour
pas être HS) de visual studio, alors le bouquin là... Même pas en rêve !

PS : Pourquoi tant de noms slaves dans le monde du C++ (cf le newsgroup
anglophone (pas mal de noms de cette origine),

strouztruc
Bjarne Stroustrup, né au Danemark, vivant aux USA.


, alexandrescu,
Andrei Alexandrescu, né en Roumanie (?), vivant aux USA.


etc.))... Le C++ c'est un peu comme les échecs ?? Hein ?


Bin, y plein d'autres noms, qui ne m'ont pas tous l'air slaves : Koenig,
Vandervorde, Coplien, Dos Reis, Stepanov, Sutter, Plauger, Kanze,
Spicer, et plein d'autres... (1)

(1) Ces noms sont dans le désordre le plus total, et sans aucun soucis
de complétude.

--
Loïc


Avatar
Philippe Guglielmetti
"Loïc Joly" a écrit
Bjarne Stroustrup, né au Danemark, vivant aux USA.

, alexandrescu,
Andrei Alexandrescu, né en Roumanie (?), vivant aux USA.


etc.))... Le C++ c'est un peu comme les échecs ?? Hein ?


Bin, y plein d'autres noms, qui ne m'ont pas tous l'air slaves : Koenig,
Vandervorde, Coplien, Dos Reis, Stepanov, Sutter, Plauger, Kanze,
Spicer, et plein d'autres... (1)


en fait, beaucoup de langages de programmation modernes ont des racines
européennes, plus précisément de Zürich ou Niklaus Wirth a développé le
Pascal, puis le Modula-2 (et maintenan Oberon). ADA en est directement
inspiré. Philippe Kahn, un Français, a démocratisé les langages sur PC en
faisant le compilateur Turbo-Pascal (1/10ème du prix des compilos Microsoft
et 10x plus rapide à l'époque). Maintenant sa boite s'appelle Borland, et le
produit Delphi. A la même époque, Logitech vendait un compilateur Modula-2
dans le monde entier.
Les ricains avaient pondu un horrible macro-assembleur appellé C, Stroustrup
en a fait un langage en y ajoutant les "++" de la rigueur européenne. Et si
vous regardez C#, vous verrez que comme les ricains ne comprennent pas les
subtilités, ils les interdisent....
L'europe est à mon avis toujours très active dans la recherche en langages
de programmation : Prolog, Eiffel, Occam, Modelica...
Ce qui n'est pas normal, c'est que les compilateurs commerciaux soient tous
made in USA.
--
Philippe Guglielmetti - www.dynabits.com


Avatar
Fabien LE LEZ
On Wed, 29 Oct 2003 06:35:39 +0100, "Philippe Guglielmetti"
wrote:

Ce qui n'est pas normal, c'est que les compilateurs commerciaux soient tous
made in USA.


Arf... Je m'imagine bien essayer de créer une entreprise en France
pour commercialiser un produit que j'aurais inventé, tiens...

--
;-)

Avatar
_M.B._
"Philippe Guglielmetti" a écrit dans le message news:
3f9f51a5$0$3674$
Et si
vous regardez C#, vous verrez que comme les ricains ne comprennent pas les
subtilités, ils les interdisent....


Pourrais-tu preciser un peu ?

MB

Avatar
_M.B._
"Loïc Joly" a écrit dans le message news:
bnmtn7$ov9$

Bin, y plein d'autres noms, qui ne m'ont pas tous l'air slaves :
...... Dos Reis .....



C'est qui ?

MB

Avatar
Philippe Guglielmetti
"Philippe Guglielmetti" a écrit:
Et si vous regardez C#, vous verrez que comme les ricains ne comprennent
pas les


subtilités, ils les interdisent....
Pourrais-tu preciser un peu ?

un peu alors. Le # de C# est censé ajouter deux + à C++, mais en fait il

enlève pas mals de trucs comme l'héritage multiple, la surcharge
d'opérateurs etc.
voir par exemple
http://developpeur.journaldunet.com/tutoriel/csharp/021030csharp_diffcpp.shtml
Je reconnais qu'il apporte cependant certaines simplifications agréables.
--
Philippe Guglielmetti - www.dynabits.com


1 2 3 4