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

Problèmes d'héritage

32 réponses
Avatar
No_Name
Bonjour,

Je travaille sur une application en C++ pour laquelle j'ai plusieurs
niveaux d'héritage :

A = Classe mère
Classe B = Hérite de A
Classe C = Hérite de B

Je voudrais pouvoir facilement transformer des objets de type B en
objets de type C et inversément.

Pour passer de C à B, j'imagine qu'un simple cast suffira, sachant
qu'en faisant cela, je perdrai les données qui font la sécificité de C
(puisque le but est de me retrouver avec un objet de type B).

Par contre, je ne vois pas bien comment je peux passer de B à C ?
J'envisageais de doter la classe C d'une fonction permettant de créer
un objet de type C à partir d'un objet de type B, en initialisant les
données supplémentaires à des valeurs par défaut, mais je ne suis pas
complètement sur de cette solution.

Et les fonctions de création d'un objet de type B en objet de type C
doivent elle effectivement être des méthodes de la classe C ?

Merci de vos conseils et suggestions.

10 réponses

1 2 3 4
Avatar
pjb
No_Name writes:

Bonjour,

Je travaille sur une application en C++ pour laquelle j'ai plusieurs
niveaux d'héritage :

A = Classe mère
Classe B = Hérite de A
Classe C = Hérite de B

Je voudrais pouvoir facilement transformer des objets de type B en
objets de type C et inversément.

Pour passer de C à B, j'imagine qu'un simple cast suffira, sachant
qu'en faisant cela, je perdrai les données qui font la sécificité de C
(puisque le but est de me retrouver avec un objet de type B).

Par contre, je ne vois pas bien comment je peux passer de B à C ?
J'envisageais de doter la classe C d'une fonction permettant de créer
un objet de type C à partir d'un objet de type B, en initialisant les
données supplémentaires à des valeurs par défaut, mais je ne suis pas
complètement sur de cette solution.

Et les fonctions de création d'un objet de type B en objet de type C
doivent elle effectivement être des méthodes de la classe C ?

Merci de vos conseils et suggestions.




Dans le second cas, le mieux c'est d'écrire un constructeur dans la
classe C prenant un B duquel on va copier les informations:


class C:public B{
public:

C(const B& b){
this->member1=b.member1;
this->member2=b.member2;
...
this->memberN=b.memberN;
}
...
};

B b1;
C c(b1);
B b2=c;


Et si je ne me trompe, on pourra aussi écrire:

C c±;


--
__Pascal Bourguignon__
Avatar
No_Name
No_Name avait écrit le 1/27/2009 :
Bonjour,

Je travaille sur une application en C++ pour laquelle j'ai plusieurs niveaux
d'héritage :

A = Classe mère
Classe B = Hérite de A
Classe C = Hérite de B

Je voudrais pouvoir facilement transformer des objets de type B en objets de
type C et inversément.

Pour passer de C à B, j'imagine qu'un simple cast suffira, sachant qu'en
faisant cela, je perdrai les données qui font la sécificité de C (puisque le
but est de me retrouver avec un objet de type B).

Par contre, je ne vois pas bien comment je peux passer de B à C ?
J'envisageais de doter la classe C d'une fonction permettant de créer un
objet de type C à partir d'un objet de type B, en initialisant les données
supplémentaires à des valeurs par défaut, mais je ne suis pas complètement
sur de cette solution.

Et les fonctions de création d'un objet de type B en objet de type C doivent
elle effectivement être des méthodes de la classe C ?

Merci de vos conseils et suggestions.



Suite à mes tests, voici qques précisions :

ma classe B

ma classe C a un héritage multiple de la classe B et de la classe Z.
Observé avec le débuggeur, mon objet C est donc un objet de type B
disposant en plus des propriétés d'un objet de type Z (logique,
puisqu'il hérite des deux).

Par contre, quand j'exécute le code suivant :

B *b = (B *)c;

je constate que b est désormais un pointeur vers un objet de type C
auquel se rajoutent les propriétés de la classe B, alors que ce que je
cherche, c'est retransformer mon objet C en objet de type B.

Merci de vos conseils pour atteindre ce but.
Avatar
Fabien LE LEZ
On Tue, 27 Jan 2009 10:56:24 +0100, No_Name :

J'envisageais de doter la classe C d'une fonction permettant de créer
un objet de type C à partir d'un objet de type B,



C'est ça. Sauf qu'une telle fonction s'appelle généralement un
"constructeur".
Avatar
Fabien LE LEZ
On Tue, 27 Jan 2009 11:15:31 +0100, No_Name :

B *b = (B *)c;

je constate que b est désormais un pointeur vers un objet de type C
auquel se rajoutent les propriétés de la classe B, alors que ce que je
cherche, c'est retransformer mon objet C en objet de type B.



Pourquoi diable essaies-tu de bidouiller avec des pointeurs ?

C c; // Objet c de classe C
B b (c); // On construit un objet b de classe B à partir de c. Les
membres communs à B et C sont automatiquement copiés. Ça fonctionne
parce que C hérite de B.

Dans l'autre sens :

B b; // Objet b de classe B
C c (b); // On appelle le constructeur "C::C (B const&)", s'il existe.
Sinon c'est une erreur. Le fait que C hérite de B n'intervient pas.
Avatar
Fabien LE LEZ
On Tue, 27 Jan 2009 11:32:11 +0100, Michael DOUBEZ
:

En supposant que B ait un constructeur par copie.



Y a-t-il des cas où une classe n'a pas de constructeur par copie ?

(Bien sûr, il peut être inaccessible, car déclaré privé.)
Avatar
Michael DOUBEZ
Pascal J. Bourguignon wrote:
No_Name writes:

Bonjour,

Je travaille sur une application en C++ pour laquelle j'ai plusieurs
niveaux d'héritage :

A = Classe mère
Classe B = Hérite de A
Classe C = Hérite de B

Je voudrais pouvoir facilement transformer des objets de type B en
objets de type C et inversément.




[snip]

Et les fonctions de création d'un objet de type B en objet de type C
doivent elle effectivement être des méthodes de la classe C ?




[snip]
Dans le second cas, le mieux c'est d'écrire un constructeur dans la
classe C prenant un B duquel on va copier les informations:


class C:public B{
public:

C(const B& b){
this->member1=b.member1;
this->member2=b.member2;
...
this->memberN=b.memberN;
}



Ou plus simplement:
C(const B& b):B(b),.../* autres membres de C */
{
//...
}

En supposant que B ait un constructeur par copie.

...
};

B b1;
C c(b1);
B b2=c;


Et si je ne me trompe, on pourra aussi écrire:

C c±;



Oui et on a en bonus la conversion automatique en passage de paramètre
aussi. En fonction de ce qu'on veut il peut être utile de rendre le
constructeur explicit.

--
Michael
Avatar
Fabien LE LEZ
No_Name wrote:

c'est retransformer mon objet C en objet de type B.





On Tue, 27 Jan 2009 11:40:38 +0100, Michael DOUBEZ
:

Je n'avais pas compris que tu voulais faire du polymorphisme.



J'ai justement l'impression qu'il n'en veut pas -- il veut un objet de
classe B plutôt qu'un B* pointant vers un C.

Enfin bref, le conseil du jour : n'utiliser de pointeurs que si on a
une raison explicite de le faire.
Avatar
Michael DOUBEZ
No_Name wrote:
No_Name avait écrit le 1/27/2009 :
Bonjour,

Je travaille sur une application en C++ pour laquelle j'ai plusieurs
niveaux d'héritage :

A = Classe mère
Classe B = Hérite de A
Classe C = Hérite de B

Je voudrais pouvoir facilement transformer des objets de type B en
objets de type C et inversément.

Pour passer de C à B, j'imagine qu'un simple cast suffira, sachant
qu'en faisant cela, je perdrai les données qui font la sécificité de C
(puisque le but est de me retrouver avec un objet de type B).

Par contre, je ne vois pas bien comment je peux passer de B à C ?
J'envisageais de doter la classe C d'une fonction permettant de créer
un objet de type C à partir d'un objet de type B, en initialisant les
données supplémentaires à des valeurs par défaut, mais je ne suis pas
complètement sur de cette solution.

Et les fonctions de création d'un objet de type B en objet de type C
doivent elle effectivement être des méthodes de la classe C ?

Merci de vos conseils et suggestions.



Suite à mes tests, voici qques précisions :

ma classe B

ma classe C a un héritage multiple de la classe B et de la classe Z.
Observé avec le débuggeur, mon objet C est donc un objet de type B
disposant en plus des propriétés d'un objet de type Z (logique,
puisqu'il hérite des deux).

Par contre, quand j'exécute le code suivant :

B *b = (B *)c;

je constate que b est désormais un pointeur vers un objet de type C
auquel se rajoutent les propriétés de la classe B, alors que ce que je
cherche, c'est retransformer mon objet C en objet de type B.



Le cast du C est trop puissant. Tu peux utiliser static_cast<>() ou tout
simplement aucun cast (il est automatique).

Je n'avais pas compris que tu voulais faire du polymorphisme.

--
Michael
Avatar
Michael DOUBEZ
Fabien LE LEZ wrote:
On Tue, 27 Jan 2009 11:32:11 +0100, Michael DOUBEZ
:

En supposant que B ait un constructeur par copie.



Y a-t-il des cas où une classe n'a pas de constructeur par copie ?



D'accord, j'ai été imprécis:
"En supposant que B supporte la construction par copie."


(Bien sûr, il peut être inaccessible, car déclaré privé.)




Ou alors il hérite ou possède un membre d'une classe qui l'a déclaré privé.

--
Michael
Avatar
No_Name
Fabien LE LEZ a couché sur son écran :
No_Name wrote:

c'est retransformer mon objet C en objet de type B.





On Tue, 27 Jan 2009 11:40:38 +0100, Michael DOUBEZ
:

Je n'avais pas compris que tu voulais faire du polymorphisme.



J'ai justement l'impression qu'il n'en veut pas -- il veut un objet de
classe B plutôt qu'un B* pointant vers un C.

Enfin bref, le conseil du jour : n'utiliser de pointeurs que si on a
une raison explicite de le faire.



Merci pour les réponses de tous, qui m'ont permis d'aboutir aux
résultats suivants :


Passage de B vers C :

B *cd = new B();
C cdc(*cd);

me donne bien un objet de type C à partir d'un objet de type B (suite à
écriture d'un constructeur par recopie).


Par contre, pour le passage de C vers B, j'ai testé :

B *cq(C);
ou bien : B *cq = static_cast<B *>(cqc); (avec cqc pointant vers un
objet de type C)

mais à chaque fois, d'après le débuggeur, j'obtiens le même résultat :
cq pointe vers un objet bizarre, qui est un objet de type C auquel
s'ajoutent les propriétés d'un objet de type B. Alors que mon but et
d'obtenir un objet de type B à partir d'un objet de type C, en perdant
bien entendu les propriétés supplémentaires qui font que C est une
spécialisation de B.

Merci.
1 2 3 4