OVH Cloud OVH Cloud

héritage ou nouvelle classe?

46 réponses
Avatar
Zoubidaman
Bonsoir,

j'ai une classe Possessions:

class Possessions
{
private:
//Le début et la fin d'une pause
typedef pair<int,int> Pauses;

//La liste des pauses
typedef vector<Pauses> ListePauses;
typedef ListePauses::iterator ite_Pauses;
ListePauses LP;

int __fastcall DureePause();
public:
int DebutPossession,FinPossession;
AnsiString ActiondeFin;
TColor CouleurActiondeFin;

Possessions();

Possessions(
int DebutPossession,
int FinPossession,
const ListePauses & VecteurPauses,
AnsiString ActiondeFin,
TColor CouleurActiondeFin)
:
DebutPossession(DebutPossession),
FinPossession(FinPossession),
LP(VecteurPauses),
ActiondeFin(ActiondeFin),
CouleurActiondeFin(CouleurActiondeFin)
{}

const ListePauses & AccesListePauses() const { return this->LP; }

int __fastcall DureePossession();
};

J'ai besoin d'une classe Strategies, qui ait la même partie private, mais
avec la partie publique différente, car j'ai besoin de moins de
variables...

Comme je ne connais (pour l'instant) rien à l'héritage, je voulais savoir
si j'avais besoin de passer par là, ou bien s'il fallait que je crée une
nouvelle classe...

Merci d'avance...

10 réponses

1 2 3 4 5
Avatar
Michaël Delva
Ai-je besoin de préciser que ça commence à devenir sérieux ?


Non, pas besoin... Je sais que c'est sérieux quand je ne comprends rien ;)

Néanmoins, je ne suis pas sûr que tout cela soit vraiment nécessaire... (Ou
peut-être que si, mais comme je ne vois pas comment ça peut tourner, je ne
m'en rends pas compte??)


(mais je dois dire que je trouve que la conception en générale est
bien plus stimulante que la programmation de bourrins faisant office
de front-end d'accès aux bases de donnée ;) )

Chris



Oui, c'est vrai...



--
---------------------------------------
http://oppc.free.fr

Avatar
Fabien LE LEZ
On 11 Aug 2003 22:46:24 GMT, Zoubidaman
wrote:

typedef pair<int,int> Pauses;


[Je réponds ici car je ne retrouve pas le message ad hoc]

Perso, je n'ai jamais utilisé std::pair<>, sauf en y étant obligé (via
std::map<>::iterator par exemple). C'est tellement simple de faire
miexu (comprendre : plus adapté à chaque cas) que je ne vois pas bien
l'intérêt de cette classe.


--
Tout sur fr.* (FAQ, etc.) : http://www.usenet-fr.net/fur/
et http://www.aminautes.org/forums/serveurs/tablefr.html
Archives : http://groups.google.com/advanced_group_search
http://www.usenet-fr.net/fur/usenet/repondre-sur-usenet.html

Avatar
Michaël Delva
Fabien LE LEZ wrote in
news::

On 12 Aug 2003 09:06:40 GMT, "Michaël Delva"
wrote:

double Duree();


int, plutôt, non ?


Oui, je l'avais mis... erreur d'inattention (bien que c'est toi qui ait
mis double dans le premier exemple que tu m'as proposé ;) )

public:
typedef vector<Intervalle_Temps> ListePauses;


Ça marche, ça ? Tu as dû mettre un "using namespace std;" quelque
part, non ? Dangereux...



Oui, j'ai mis un "using namespace std;" En quoi est-ce dangereux? Je
trouve rébarbatif de toujours mettre std::


void push (const Intervalle_Temps & intervalle);


Je préférerais "push_back", ou "Ajouter"... Le terme "push" est
généralement réservé aux piles.


Je ne savais pas, je vais corriger...

--
Intervalle_Temps::Intervalle_Temps()
{
debut = 0;
fin = 0;
}


Pourquoi ne l'écris-tu pas comme les autres constructeurs ?

Intervalle_Temps::Intervalle_Temps()
: debut (0), fin (0)
{}

[Bon, OK, pour des entiers, ça n'a pas grande importance]


Ca y est, c'est changé...

int Possessions::DureePossession()


Cette fonction devrait être déclarée "const", puisqu'elle ne modifie
aucun membre.


Changé ;)

--
---------------------------------------
http://oppc.free.fr


Avatar
drkm
Fabien LE LEZ writes:

On 12 Aug 2003 02:29:04 GMT, Zoubidaman
wrote:

int CalculeDuree (Intervalle const& intervalle_general,
GestionPauses const& pauses);


J'ai souvent lu qu'il était déconseillé de créer des méthodes qui
ne sont pas encapsulées dans une classe...


Dans un langage qui a des méthodes, peut-être. En C++ il n'y a que
des fonctions. Certaines, notamment celles qui accèdent à des
données privées d'une classe, doivent être membres de cette
classe. Mais s'il n'y a aucune raison pour une fonction donnée
d'être membre d'une classe (comme c'est le cas ici), elle peut tout
à fait être libre. Ce qui peut être douteux, par contre, c'est de
déclarer une fonction libre amie d'une classe, et ainsi lui laisser
accès aux données privées.


Il y a également des raisons pour ne pas faire des membres de
certaines fonctions. Cfr. par exemple l'article « Generalized String
Manipulation: Access Shims and Type Tunneling », Matthew Wilson, CUJ,
August 2003. Il introduit la notion de « shim ».

Un exemple, dont je ne sais plus s'il est tiré de l'article, serait
une manière de récupérer la longueur d'une chaîne de ca ractères,
applicable à différents types. Par exemple :

int str_len( char const * s )
{
return std::strlen( s ) ;
}

int str_len( std::string const & s )
{
return s.length() ;
}

int str_len( AnsiString const & s )
{
return s.Len ; // Je ne connais pas AnsiString.
}

int str_len( CString const & s )
{
// Je ne connais pas CString.
return static_cast< int >(
fun_namespace::obtenir_valeur_FROM_Clef(
s.la_longueur_de_LaChaineEn_entierNonStandard()->key
)
) ;
}

template < typename String >
void f( String const & s )
{
int length = str_len( s ) ;
// ...
}

Évidemment, ces considérations sont un peu en dehors de la
conception de la classe elle-même, mais donnent des raisons d'utiliser
dans certains cas des fonctions libres plutôt que des fonctions
membres, quite à créer soi-même ces fonctions libres qui ne font
qu'encapsuler l'appel à une fonction membre.

Et j'aime assez la définition d'interface de classe de Sutter.
Puisque je suppose que c'est en partie cette notion qui a fait dire au
PO « J'ai souvent lu qu'il était déconseillé de cré er des méthodes qui
ne sont pas encapsulées dans une classe... ».

Je n'ai pas « Exceptional C++ » sous la main, mais la défini tion de
Sutter ressemble grosso-modo à « L'ensemble des membres publiques et
des fonctions libres en rapport avec cette classe et livrées avec
cette dernière ». En rapport avec cette classe signifie qu'un des
paramètres de la fonction libre est du type de la classe, et livrà ©e
avec celle-ci signifie dans le même espace de noms [*] et/ou le mà ªme
en-tête. Il suffit de penser à la surcharge de l'opérateur de sortie
vers un flux standard pour une classe.

[*] C'est, si je me souviens bien, ce qui a conduit à l'adoption,
et avant à la conception, du Koenig Lookup.

--drkm



Avatar
Michaël Delva
Tu as moins de paramètres fournis à ton constructeur si tu en fournis
via des objets que tu as construits avant. Pour être plus clair, si tu
fournis un paramètre intervalle au lieu de debut, fin et pause, c'est
quand même moins lourd à utiliser. C'est aussi un peu plus sur, car il
est facile de se tromper sur l'ordre des paramètres que tu fournis,
particulièrement quand tu en as beaucoup de même type (les trois que
je cite étant du type int, c'est facile de balancer la pause à la
place de début)

Chris




Oui, mais l'écriture de la construction est plus longue:

Possessions(Intervalle_Temps(10,120),vecteur_pauses,"T2L",0);

par exemple

--
---------------------------------------
http://oppc.free.fr

Avatar
Michaël Delva
Voilà pourquoi ça me "choque" un peu:

j'utilise le code suivant pour enregistrer en mémoire les possessions
(dans la classe Analyse_Donnees):

//Nom du joueur + Possessions
typedef multimap<AnsiString,Possessions> TtesPoss1Joueur;
typedef TtesPoss1Joueur::iterator ite_Possession_Joueur;

//Paire d'iterateurs pour le equal_range()
typedef pair<ite_Possession_Joueur,ite_Possession_Joueur>
Paire_ite_Possession_Joueur;

//Contiendra l'intervalle des iterateurs pour le equal_range
typedef pair<ite_Possession_Joueur,ite_Possession_Joueur>
Paire_ite_Possession_Joueur;

//Equipes + Joueurs
typedef map<AnsiString,TtesPoss1Joueur> ToutesPossessions;
typedef ToutesPossessions::iterator ite_Possession_Equipe;

Bon, ça marche, là n'est pas le problème (quoi que si vous trouvez que
c'est un problème de procéder de la sorte, dites le moi!!)

Quand je veux récupérer mes données, j'en arrive à ça par exemple

for (Analyse_Donnees::ite_Possession_Joueur GO_Possession = PiPJ.first;
GO_Possession != PiPJ.second; ++GO_Possession)
{
int DebutPossession = GO_Possession->second.debut_et_fin.debut;
}

C'est cette succession de "." qui me semblait bizarre...

Pas à vous?
--
---------------------------------------
http://oppc.free.fr
Avatar
Michaël Delva
Bon, ben voilà le dernier argument qui va me convaincre de ne pas hésiter à
utiliser plus souvent les classes...

En fait je partais du principe que si un code utilise beaucoup de classes
(évidemment pas les gros projets), c'est que peut-être il y a une erreur de
concepion...

A méditer donc...

--
---------------------------------------
http://oppc.free.fr
Avatar
Michel Michaud
Dans news:,
C'est mieux de passer par des structures que par la STL?
(Intervalle au lieu de pair<int,int>)


C'est mieux d'utiliser une structure ou classe selon la raison
qui a poussé à sa création. Prendre pair pour garder des
données clairement identifiables (comme début et fin) est
aussi mauvais que de prendre un vector<int> et d'y mettre toutes
données membres de type int. En fait, on peut se demander
pourquoi la STL (et par suite la SL) n'a pas créé de petites
structures spécialisées pour les cas où elle utilise plutôt
pair. Lest first et second sont parfois facilement à confondre...

[...]
J'ai souvent lu qu'il était déconseillé de créer des méthodes qui
ne sont pas encapsulées dans une classe...


Où as-tu lu ça ?

--
Michel Michaud
http://www.gdzid.com
FAQ de fr.comp.lang.c++ :
http://www.cmla.ens-cachan.fr/~dosreis/C++/FAQ/

Avatar
Fabien LE LEZ
On Tue, 12 Aug 2003 22:35:03 -0400, "Michel Michaud"
wrote:

J'ai souvent lu qu'il était déconseillé de créer des méthodes qui
ne sont pas encapsulées dans une classe...


Où as-tu lu ça ?


Dans un bouquin de Java ?


--
Tout sur fr.* (FAQ, etc.) : http://www.usenet-fr.net/fur/
et http://www.aminautes.org/forums/serveurs/tablefr.html
Archives : http://groups.google.com/advanced_group_search
http://www.usenet-fr.net/fur/usenet/repondre-sur-usenet.html


Avatar
Julien Blanc
Fabien LE LEZ wrote:
On Tue, 12 Aug 2003 22:35:03 -0400, "Michel Michaud"
wrote:


J'ai souvent lu qu'il était déconseillé de créer des méthodes qui
ne sont pas encapsulées dans une classe...


Où as-tu lu ça ?



Dans un bouquin de Java ?


dans des bouquins d'intégristes, diront certains :).

En fait, il me parait beaucoup plus sage d'encapsuler les méthodes au
moins dans un namespace. Et dans les langages où on ne dispose pas de
namespace, on utilise une classe vide à la place. C'est somme toute peu
coûteux et plus sage, car permettant d'éviter des conflits de noms et
améliorant l'évolutivité du code.

(évidemment, je parle de méthodes à portée globale, ici).

--
Julien Blanc. Equipe cadp. VERIMAG. Grenoble. France.



1 2 3 4 5