OVH Cloud OVH Cloud

Héritage et algorithme

14 réponses
Avatar
Michael
Bonsoir à tous,

soient les classes suivantes:

class ObjetBase
{
ObjetBase() {}
};

class ObjetThumb : public ObjetBase
{
ObjetThumb() : ObjetBase() {}

void DrawThumb() { }
};

class ObjetText : public ObjetBase
{
ObjetText() : ObjetBase() {}

void DrawText() { }
};

class ListeBase
{
protected:
std::vector<ObjetBase*> liste;
};

class ListeThumb : public ListeBase
{
public:
void foo();
};

class ListeText : public ListeBase
{
public:
void foo();
};

////////////////////////////

J'aurais voulu implémenter les fonctions foo comme suit:

void ListeThumb::foo()
{
std::for_each(liste.begin(),liste.end(),std::mem_fun
(&ObjetThumb::DrawThumb));
}

void ListeText::foo()
{
std::for_each(liste.begin(),liste.end(),std::mem_fun
(&ObjetText::DrawText));
}

Mais bien sûr ça ne fonctionne pas, j'ai les messages d'erreur suivants
(BCB6)

[C++ Erreur] _algo.h(65): E2034 Impossible de convertir 'ObjetBase *' en
'const ObjetThumb *'
[C++ Erreur] _algo.h(65): E2342 Mauvaise correspondance de type dans le
paramètre '__x' ('const ObjetThumb * const &' désiré, 'ObjetBase *'
obtenu)

Alors du coup je suis obligé de déclarer DrawThumb et DrawText virtuelles
dans ObjetBase, alors qu'elles ne sont utilisées respectivement que dans
ObjetThumb et ObjetText.

Y a-t-il moyen de faire autrement?

Sinon par rapport au même cas de figure, existe-il un pattern quelconque,
ou une méthode à suivre, pour m'assurer que les ObjetThumb sont bien
utilisés par ListeThumb et ObjetText par ListeText?

Merci d'avance

Mike

4 réponses

1 2
Avatar
dagecko
Des fois se procurer et lire un bon bouquin sur le sujet
qu'on ne comprends pas (ici C++) ça peut éviter de faire
si mal aux autres et ça peut vous faire du bien.
Avatar
Fabien LE LEZ
On Fri, 20 Jan 2006 14:15:35 +0100, Fabien LE LEZ
:

bool ObjetOK (ObjetBase * objet)
{
return dynamic_cast <ObjetThumb*> (objet) != 0;
}


Note : il doit y avoir moyen de templatiser tout ça...

Avatar
Cyrille
On Fri, 20 Jan 2006 14:15:35 +0100, Fabien LE LEZ
:

bool ObjetOK (ObjetBase * objet)
{
return dynamic_cast <ObjetThumb*> (objet) != 0;
}


Note : il doit y avoir moyen de templatiser tout ça...


Un truc comme ça peut-être:

template <class T>
class ListeBase
{
private:
std::vector<T*> liste;
protected:
void AddObject(T * objet)
{
liste.push_back(objet);
}
}

class ListeObjetsThumb : public ListeBase<ObjetThumb>
{
public:
void CreateObject()
{
ObjetThumb * objet = new ObjetThumb();
AddObject(objet);
//Gestion de la représentation sous forme graphique de l'objet
}
};

Comme ça la vérification de type se fait à la compilation.

--
Réhabilitez Garfieldd!
http://minilien.com/?HpC5r1qClU


Avatar
Michael
Un truc comme ça peut-être:

template <class T>
class ListeBase
{
private:
std::vector<T*> liste;
protected:
void AddObject(T * objet)
{
liste.push_back(objet);
}
}

class ListeObjetsThumb : public ListeBase<ObjetThumb>
{
public:
void CreateObject()
{
ObjetThumb * objet = new ObjetThumb();
AddObject(objet);
//Gestion de la représentation sous forme graphique de
l'objet
}
};

Comme ça la vérification de type se fait à la compilation.



J'avais pensé à la même chose...

Seulement j'ai du coup un autre souci:

J'ai la classe suivante:

template <class T>
class ListeBase
{
};

class ListeThumb : public ListeBase<ObjetThumb>
{
};


class ListeText : public ListeBase<ObjetText>
{
};


enum DisplayMode { dmThumb , dmText };

class Form
{
private:
boost::scoped_ptr<???> liste;
void ChangeDisplay(DisplayMode dm)
{
if (dm == dmThumb)
{
liste.reset(new ListeThumb());
}
else
{
liste.reset(new ListeText());
}
}
};

Seulement je ne sais pas quoi mettre au niveau de la définition de liste.
La seule solution que j'ai trouvé, mais je ne sais pas si c'est la bonne,
c'est de créer une classe de base pour ListeBase avec les fonctions
publiques de ListeBase en virtuel.

1 2