OVH Cloud OVH Cloud

Deriver d'un conteneur de la STL

55 réponses
Avatar
Aurélien REGAT-BARREL
Bonjour,
J'aimerais bien créer quelques classes qui dérivent de certains conteneurs
de la STL. Je sais que ces derniers ne sont pas conçus pour être dérivés,
mais sachant que le but est simplement de :
- créer un vrai nouveau type au lieu d'un typedef
- ne pas ajouter de donnée membre mais uniquement dfes fonctions

est-ce une pratique acceptable ?

Exemple:

class SortedData : public std::set<int>
{
public:
SortedData( const std::vector<int> & Vect )
{
this->insert( Vect.begin(), Vect.end() );
}

// calcule la moyenne
double Average() const
{
int total = 0;
total = std::accumulate( this->begin(), this->end(), total );
return total * 1.0 / this->size();
}
};


--
Aurélien REGAT-BARREL

10 réponses

1 2 3 4 5
Avatar
Jean-Marc Bourguet
"Aurélien REGAT-BARREL" writes:

Bonjour,
J'aimerais bien créer quelques classes qui dérivent de certains conteneurs
de la STL. Je sais que ces derniers ne sont pas conçus pour être dérivés,
mais sachant que le but est simplement de :
- créer un vrai nouveau type au lieu d'un typedef
- ne pas ajouter de donnée membre mais uniquement dfes fonctions

est-ce une pratique acceptable ?


Tant que tu n'essaies pas de detruire un type derive a partir d'un
pointeur sur le type de base, il n'y a pas de probleme de C++. Pour
le reste, il faut connaitre la situation.

A+

--
Jean-Marc
FAQ de fclc++: http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ
C++ FAQ Lite en VF: http://www.ifrance.com/jlecomte/c++/c++-faq-lite/index.html
Site de usenet-fr: http://www.usenet-fr.news.eu.org

Avatar
noone
est-ce une pratique acceptable ?


Je me pose également cette question...

Je fais actuellement autre chose et je me demande si c'est à faire...

En fait je mets ma liste comme membre privé de ma classe et je fournis
des interfaces qui donnent accès à ma liste...

Je me dis que ma méthode n'est pas clair... et que c'est même plutôt
moche, non ?

En plus si je veux parcourir ma liste de l'extérieur je suis obligé de
fournir les itérateurs begin et end en public

Que pensent les gourous de ça ?

Avatar
Aurélien REGAT-BARREL
Tant que tu n'essaies pas de detruire un type derive a partir d'un
pointeur sur le type de base, il n'y a pas de probleme de C++. Pour
le reste, il faut connaitre la situation.


A priori non, donc je vais faire ça alors.
Sinon juste pour info, si je n'ai aucune donnée membre et aucun destructeur,
ça poserait quand même un problème de détruire depuis un pointeur de base ?
Merci.

--
Aurélien REGAT-BARREL

Avatar
Fabien LE LEZ
On Thu, 20 Jan 2005 18:06:27 +0100, ""
:

En plus si je veux parcourir ma liste de l'extérieur


Mais as-tu une bonne raison de le faire ?


--
;-)

Avatar
Arnaud Debaene
Aurélien REGAT-BARREL wrote:
Tant que tu n'essaies pas de detruire un type derive a partir d'un
pointeur sur le type de base, il n'y a pas de probleme de C++. Pour
le reste, il faut connaitre la situation.


A priori non, donc je vais faire ça alors.
Sinon juste pour info, si je n'ai aucune donnée membre et aucun
destructeur, ça poserait quand même un problème de détruire depuis un
pointeur de base ?
Oui, car le compilateur va générer un destructeur par défaut non virtuel,

donc le problème demeurera.

Arnaud


Avatar
noone
On Thu, 20 Jan 2005 18:06:27 +0100, ""
:


En plus si je veux parcourir ma liste de l'extérieur



Mais as-tu une bonne raison de le faire ?




Oui c'est un programme d'électrostatique

http://s.cls.free.fr/index.php?page=fieldE

J'ai une classe "Charge" qui décrit des charges électrostatique
J'ai une classe "Charges" qui est une "collection" de toutes les charges.
Depuis mon programme principal il faut je j'affiche chaque charge...
Donc il faut parcourir "Charges" depuis l'extérieur...

C'est sûrement pas comme ça qu'il faut faire... mais bon !

D'ailleurs tant que j'y pense si des gourous du C++ pouvaient y jeter un
oeil pour me suggérer des modifs, suggestions (je pense surtout aux
bonnes pratiques du C++ que je n'ai pas... car je ne l'ai jamais
apprises...)


Avatar
Falk Tannhäuser
Aurélien REGAT-BARREL wrote:
class SortedData : public std::set<int>
{
public:
SortedData( const std::vector<int> & Vect )
{
this->insert( Vect.begin(), Vect.end() );
}

// calcule la moyenne
double Average() const
{
int total = 0;
total = std::accumulate( this->begin(), this->end(), total );
return total * 1.0 / this->size();
}
};


Pourquoi Average() doit-elle absolument être une fonction
membre ? Quelque chose comme

template<typename Container>
double Average(Container const& c)
{
return std::accumulate(c.begin(), c.end(),
static_cast<typename Container::value_type>(0 ))
/ double(c.size());
}

ne fait-elle pas l'affaire ?

Falk

Avatar
Alexandre
bonjour,

En fait je mets ma liste comme membre privé de ma classe et je fournis des
interfaces qui donnent accès à ma liste...


tu pourrais aussi hériter en mode privé de la liste. N'étant pas un gourou,
je suis incapable de te dire si c'est mieux ou moins bien, moi je fais ça
assez souvent. Mais à priori je dirais que ça ne change pas grand chose.


Je me dis que ma méthode n'est pas clair... et que c'est même plutôt
moche, non ?

En plus si je veux parcourir ma liste de l'extérieur je suis obligé de
fournir les itérateurs begin et end en public

Que pensent les gourous de ça ?


Avatar
Olivier Azeau
Arnaud Debaene wrote:
Aurélien REGAT-BARREL wrote:

Tant que tu n'essaies pas de detruire un type derive a partir d'un
pointeur sur le type de base, il n'y a pas de probleme de C++. Pour
le reste, il faut connaitre la situation.


A priori non, donc je vais faire ça alors.
Sinon juste pour info, si je n'ai aucune donnée membre et aucun
destructeur, ça poserait quand même un problème de détruire depuis un
pointeur de base ?


Oui, car le compilateur va générer un destructeur par défaut non virtuel,
donc le problème demeurera.


Si l'héritage est limité à un héritage d'implémentation comme dans
l'exemple de code posté, le plus simple est quand même de faire un
héritage privé qui évite de se poser ce genre de questions.



Avatar
Olivier Azeau
Falk Tannhäuser wrote:
Aurélien REGAT-BARREL wrote:

class SortedData : public std::set<int>
{
public:
SortedData( const std::vector<int> & Vect )
{
this->insert( Vect.begin(), Vect.end() );
}

// calcule la moyenne
double Average() const
{
int total = 0;
total = std::accumulate( this->begin(), this->end(), total );
return total * 1.0 / this->size();
}
};



Pourquoi Average() doit-elle absolument être une fonction
membre ? Quelque chose comme

template<typename Container>
double Average(Container const& c)
{
return std::accumulate(c.begin(), c.end(),
static_cast<typename Container::value_type>(0))
/ double(c.size());
}

ne fait-elle pas l'affaire ?


En rajoutant probablement dans la classe un
friend double Average<SortedData>(SortedData const& c);

Il s'agit avant tout de savoir si SortedData veut être visible de
l'extérieur comme un std::set<int> (héritage de type) ou si c'est juste
un héritage d'implémentation.
L'héritage de type sur des container stl étant source de problèmes, il
vaut probablement mieux opter pour un héritage privé.


1 2 3 4 5