Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Héritage ou pas?

20 réponses
Avatar
Michaël Delva
Bonsoir à tous,

j'ai la classe suivante, qui correspond à une séquence temporelle, qui
commence et finit à deux temps différents, et dont on peut calculer la
durée:

//-----------------------------------------------------------------------
struct SJ_Intervalle_Temps
{
LONGLONG debut,fin;

__fastcall SJ_Intervalle_Temps(const LONGLONG & debut_int,const
LONGLONG & fin_int) : debut(debut_int),fin(fin_int) {}

bool operator==(const SJ_Intervalle_Temps & compar) const
{ return (debut == compar.debut && fin == compar.fin); }

bool operator<(const SJ_Intervalle_Temps & compar) const
{ return (debut < compar.debut); }

inline LONGLONG __fastcall duree_intervalle() const
{ return fin - debut; }
};
//-----------------------------------------------------------------------

J'ai ensuite la classe suivante:

//-----------------------------------------------------------------------
class SJ_Sequence
{
public:
SJ_Intervalle_Temps debut_et_fin;

int index_action_fin,
index_action_debut;

//blablabla...

LONGLONG __fastcall DureeSequence() const
{ return debut_et_fin.duree_intervalle(); }
};
//-----------------------------------------------------------------------

J'ai dans cette classe un membre SJ_Intervalle_Temps qui me permet de
déterminer le début et la fin de cette séquence, et que j'utilise pour
calculer la durée de la séquence.

Mais ne serait-il pas plus simple d'utiliser l'héritage dans ce cas de
figure?

J'avoue (encore une fois ;-) ) ne pas être au point sur cette notion.

Si je déclare SJ_Sequence comme héritant de SJ_Intervalle_Temps, les
membres LONGLONG debut et fin seront accessibles depuis SJ_Sequence, c'est
bien ça?
Et donc il n'y aurait plus besoin de définir une fonction DureeSequence
dans SJ_Sequence, la fonction de la classe SJ_Intervalle_Temps étant là?

Je me trompe, ou bien je peux faire comme ça?

Merci d'avance!

10 réponses

1 2
Avatar
Arnaud Debaene
Michaël Delva wrote:
Bonsoir à tous,
Bonsoir.


j'ai la classe suivante, qui correspond à une séquence temporelle, qui
commence et finit à deux temps différents, et dont on peut calculer la
durée:

struct SJ_Intervalle_Temps
{
<snip>

};

J'ai ensuite la classe suivante:

class SJ_Sequence
{
public:
SJ_Intervalle_Temps debut_et_fin;
<snip>

};

J'ai dans cette classe un membre SJ_Intervalle_Temps qui me permet de
déterminer le début et la fin de cette séquence, et que j'utilise pour
calculer la durée de la séquence.

Mais ne serait-il pas plus simple d'utiliser l'héritage dans ce cas de
figure?


Sauf cas particulier, ce qui doit te décider à utiliser l'héritage public,
ce n'est pas la simplicité (apparente) de programmation, mais la sémantique
de tes objets : une classe B ne doit hériter d'une classe A que si
l'assertion "un objet B est un objet A" est vraie. On appelle ca le principe
de substitution de Liskov (LSP).

Je n'ai pas le contexte pour comprendre ce qu'est une "séquence" dans ton
cas, mais si une séquence *est* un intervalle de temps, alors utilise
l'héritage, sinon reste avec l'aggregation.

Arnaud

Avatar
Michaël Delva
"Arnaud Debaene" wrote in
news:404654ab$0$28435$:

Sauf cas particulier, ce qui doit te décider à utiliser l'héritage
public, ce n'est pas la simplicité (apparente) de programmation, mais
la sémantique de tes objets : une classe B ne doit hériter d'une
classe A que si l'assertion "un objet B est un objet A" est vraie. On
appelle ca le principe de substitution de Liskov (LSP).


Tu aurais des infos là dessus, url?

Je n'ai pas le contexte pour comprendre ce qu'est une "séquence" dans
ton cas, mais si une séquence *est* un intervalle de temps, alors
utilise l'héritage, sinon reste avec l'aggregation.

Et comme c'est le cas, j'ai "tenté" l'héritage, et ça marche...


Je trouve ça plus simple comme ça en plus...

Merci de ta réponse!

Avatar
Fabien LE LEZ
Si tu écris

class D : public B ...

les codes ci-dessous doivent avoir un sens :

void f (B& b);

int main()
{
D d;
f (d);
}


int main()
{
B* ptr= new D;
}


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

Si tu écris

class D : public B ...

les codes ci-dessous doivent avoir un sens :

void f (B& b);

int main()
{
D d;
f (d);
}


Ca, j'ai compris, c'est passer dans une fonction qui a comme argument la
classe "héritée" une instance de la classe qui "hérite"


int main()
{
B* ptr= new D;
}




Là par contre je suis pas sûr: on peut instancier la classe "héritée" grâce
à la classe qui "hérite"?

PS: je ne pense pas que "héritée" et qui "hérite" soient les appellations
justes...

Avatar
Michel Michaud
Dans news:, Michaël
"Arnaud Debaene" wrote in
news:404654ab$0$28435$:

Sauf cas particulier, ce qui doit te décider à utiliser l'héritage
public, ce n'est pas la simplicité (apparente) de programmation,
mais la sémantique de tes objets : une classe B ne doit hériter
d'une classe A que si l'assertion "un objet B est un objet A" est
vraie. On appelle ca le principe de substitution de Liskov (LSP).


Tu aurais des infos là dessus, url?


Comme dirait je ne sais qui, Altavista est ton ami :-) Mais
attention, Barbara (Liskov) n'a pas dit exactement ce que la
plupart des gens pensent qu'elle a dit ! Alors tu n'en tireras
probablement pas grand chose (en fait, elle a dit quelque chose
comme « If for each object o1 of type S there is an object o2 of
type T such that for all programs P defined in terms of T, the
behaviour of P is unchanged when o1 is substituted for o2 then S
is a subtype of T. »)...

Je n'ai pas le contexte pour comprendre ce qu'est une "séquence"
dans ton cas, mais si une séquence *est* un intervalle de temps,
alors utilise l'héritage, sinon reste avec l'aggregation.

Et comme c'est le cas, j'ai "tenté" l'héritage, et ça marche...



Ce n'est pas un critère suffisant. Si ça marche aussi bien sans
l'héritage, il vaut probablement mieux s'en passer.

Je trouve ça plus simple comme ça en plus...


Ce n'est pas un bon critère non plus :-(

D'après ce que je comprends de ton problème, une séquence
n'est pas une sorte d'intervalle de temps. Alors l'héritage
ne convient pas.

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


Avatar
Michel Michaud
Dans news:, Michaël
Fabien LE LEZ wrote in
news::
int main()
{
B* ptr= new D;
}




Là par contre je suis pas sûr: on peut instancier la classe
"héritée" grâce à la classe qui "hérite"?

PS: je ne pense pas que "héritée" et qui "hérite" soient les
appellations justes...



B est la « classe de base ». D est la « classe dérivée ». Ce qui
explique les noms classiques B et D pour ce genre d'exemple...

--
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 04 Mar 2004 00:22:27 GMT, "Michaël Delva"
wrote:

PS: je ne pense pas que "héritée" et qui "hérite" soient les appellations
justes...


Je confirme, on dit généralement "classe de base" (ici, B) et "classe
dérivée" (ici, D).

int main()
{
B* ptr= new D;
}


Là par contre je suis pas sûr: on peut instancier la classe "héritée" grâce
à la classe qui "hérite"?


Oui : un D* convient partout où un B* convient.

Si tu acceptes l'idée

void f (B& b);

D d;
f (d);

tu accepteras sans doute aussi

void f (B* b);

D d;
D* ptr_d= &d;
f (ptr_d);

Si tu remplaces "f" par "operator=", tu obtiens assez directement
B* ptr= new D;


--
;-)


Avatar
Fabien LE LEZ
On Wed, 3 Mar 2004 20:16:02 -0500, "Michel Michaud"
wrote:

(en fait, elle a dit quelque chose
comme « If for each object o1 of type S there is an object o2 of
type T such that for all programs P defined in terms of T, the
behaviour of P is unchanged when o1 is substituted for o2 then S
is a subtype of T. »)


Houlà, ça devient compliqué, ça. J'ai peut-être mal compris le terme
"subtype". Est-ce un équivalent de "dérivée", ou totalement autre
chose.

Prenons un exemple :

class T
{
public: virtual string nom_du_type() { return "T"; }
...
};
class S : public T
{
public: virtual string nom_du_type() { return "S"; }
...
};

void P (T &t) { cout << t.nom_du_type() << endl; }

Soit un objet o1 de classe S. P(o1) affichera "S".
Quel que soit o2 de classe T, P(o2) affichera "T".

Donc, quel que soit le contenu de S et T par ailleurs, dériver S de T
n'est pas correct ?

--
;-)

Avatar
Michaël Delva
"Michel Michaud" wrote in news:orv1c.16653$qA2.876307
@news20.bellglobal.com:

Comme dirait je ne sais qui, Altavista est ton ami :-) Mais
attention, Barbara (Liskov) n'a pas dit exactement ce que la
plupart des gens pensent qu'elle a dit ! Alors tu n'en tireras
probablement pas grand chose (en fait, elle a dit quelque chose
comme « If for each object o1 of type S there is an object o2 of
type T such that for all programs P defined in terms of T, the
behaviour of P is unchanged when o1 is substituted for o2 then S
is a subtype of T. »)...


Mouais, faudra que je relise ça moins fatigué ;-)

Je n'ai pas le contexte pour comprendre ce qu'est une "séquence"
dans ton cas, mais si une séquence *est* un intervalle de temps,
alors utilise l'héritage, sinon reste avec l'aggregation.

Et comme c'est le cas, j'ai "tenté" l'héritage, et ça marche...



Ce n'est pas un critère suffisant. Si ça marche aussi bien sans
l'héritage, il vaut probablement mieux s'en passer.

Je trouve ça plus simple comme ça en plus...


Ce n'est pas un bon critère non plus :-(

D'après ce que je comprends de ton problème, une séquence
n'est pas une sorte d'intervalle de temps. Alors l'héritage
ne convient pas.



Ben c'est quand même le cas, une séquence est un intervalle de temps...



Avatar
adebaene
"Michaël Delva" wrote in message news:...
"Arnaud Debaene" wrote in
news:404654ab$0$28435$:

Sauf cas particulier, ce qui doit te décider à utiliser l'héritage
public, ce n'est pas la simplicité (apparente) de programmation, mais
la sémantique de tes objets : une classe B ne doit hériter d'une
classe A que si l'assertion "un objet B est un objet A" est vraie. On
appelle ca le principe de substitution de Liskov (LSP).


Tu aurais des infos là dessus, url?
Google ou n'importe quel bouqin de conception objet.



Je n'ai pas le contexte pour comprendre ce qu'est une "séquence" dans
ton cas, mais si une séquence *est* un intervalle de temps, alors
utilise l'héritage, sinon reste avec l'aggregation.

Et comme c'est le cas,

Ah bon? Une séquence est un intervalle de temps? Ca représnte quoi une

séquence exactement?

Je trouve ça plus simple comme ça en plus...
Mauvaise raison : La question est de savoir si ca a un sens par

rapport à ta modélisation objet.

Arnaud


1 2