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

Relation classe Parent/Enfant et fonctions membres

8 réponses
Avatar
PurL
Bonjour,

Soit une classe Parent qui possede une variable membre nommée var1 et une
fonction membre nommée ma_fonction qui travaille sur var1.
Soit une classe Enfant dérivée de Parent qui possede une variable membre
nommée var2 et la variable héritée de Parent var1.
Enfant possède aussi ma_fonction par héritage.

Je voudrais réécrire ma_fonction au sein de Enfant car il faut travailler
sur var2, mais je voudrais aussi qu'en appelant Enfant::ma_fonction() cela
déclenche l'appel de la fonction Parent::ma_fonction() pour effectuer le
travail sur var1.

Je créé Enfant car je veux spécialiser/préciser la classe Parent mais tout
le travail qu'effectue Parent doit etre repporté dans Enfant (ca me parait
normal comme souhait)...

ex:

class Parent
{
protected:
monobjet *var1;
public:
void ma_fonction()
{
var1->AutreFonction();
}
};

class Enfant : public Parent
{
protected:
monobjet *var2;
public:
void ma_fonction()
{
var2->AutreFonction();
}
};

//application
void Fonction()
{
Enfant enfant;
enfant.ma_fonction();
//je voudrais que var1->AutreFonction() et var2->AutreFonction() soit
appellée
//car apres tout var1 appartient à enfant
}


Merci de m'expliquer comment établir ce mécanisme,

PurL

8 réponses

Avatar
Jean-Marc Bourguet
"PurL" writes:

class Parent
{
protected:
monobjet *var1;
public:
void ma_fonction()
{
var1->AutreFonction();
}
};

class Enfant : public Parent
{
protected:
monobjet *var2;
public:
void ma_fonction()
{
var2->AutreFonction();
Parent::AutreFonction();

}
};


Envisager peut-etre en plus de mettre ma_fonction en virtuel.

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
PurL
Envisager peut-etre en plus de mettre ma_fonction en virtuel.


Ca change rien :(
apparement, quand, dans la classe Enfant, on redéfini ma_fonction, celle ci
remplace/masque celle de Parent. Le plus surprenant c'est que si on définit
dans Enfant une autre fonction de meme nom avec des paramètres différents
(une surcharge), cette nouvelle fonction masquera aussi celle de Parent !!
(la je vois pas pourquoi)

PurL

Avatar
Jean-Marc Bourguet
"PurL" writes:

Envisager peut-etre en plus de mettre ma_fonction en virtuel.


Ca change rien :(


Ce n'etait qu'une suggestion sur la conception parce que si j'en crois
mon experience la plupart des membres qu'on veut modifier dans une
classe descendante sont generallement virtuels.

La solution etait au-dessus: ajouter
Parent::AutreFonction();
dans Enfant::ma_fonction().

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
Falk Tannhäuser
Jean-Marc Bourguet wrote:
class Parent
{
protected:
monobjet *var1;
public:
void ma_fonction()
{
var1->AutreFonction();
}
};

class Enfant : public Parent
{
protected:
monobjet *var2;
public:
void ma_fonction()
{
var2->AutreFonction();


Parent::AutreFonction();


Plutôt
Parent::ma_fonction();
(qui appellera 'var1->AutreFonction()' - du coup, 'var1'
pourrait même être 'private' au lieu d'être 'protected'.


}
};



Falk


Avatar
Jean-Marc Bourguet
Falk Tannhäuser writes:

Jean-Marc Bourguet wrote:
class Parent
{
protected:
monobjet *var1;
public:
void ma_fonction()
{
var1->AutreFonction();
}
};

class Enfant : public Parent
{
protected:
monobjet *var2;
public:
void ma_fonction()
{
var2->AutreFonction();
Parent::AutreFonction();



Plutôt
Parent::ma_fonction();
(qui appellera 'var1->AutreFonction()' - du coup, 'var1'
pourrait même être 'private' au lieu d'être 'protected'.


Exact; et je crains avoir recommis la meme erreur dans un autre
message.

--
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
PurL
Ce n'etait qu'une suggestion sur la conception parce que si j'en crois
mon experience la plupart des membres qu'on veut modifier dans une
classe descendante sont generallement virtuels.


Oui c'est vrai...


La solution etait au-dessus: ajouter
Parent::AutreFonction();
dans Enfant::ma_fonction().


J'avais pas vu, c'est effectivement une solution pour obtenir le résultat
souhaité mais pas la méthode souhaitée. En effet, je souhaite quelque chose
d'automatique, c'est pas tres efficace de devoir tout réécrire. Image (et
c'est le cas) que j'ai plusieurs variable à chaque niveau d'héritage et
plusieur niveau d'héritage, ca devient vite l'usine à gaz...

Il faudrait qu'il se produit le meme mécanisme que pour les construteurs par
défaut :
qd on créé une classe Enfant, son constructeur par défaut et celui de la
classe Parent sont appelés.

PurL

Avatar
Jonathan Mcdougall
Soit une classe Parent qui possede une variable membre nommée var1 et une
fonction membre nommée ma_fonction qui travaille sur var1.
Soit une classe Enfant dérivée de Parent qui possede une variable membre
nommée var2 et la variable héritée de Parent var1.
Enfant possède aussi ma_fonction par héritage.


Du code vaut parfois mille mots...

Je voudrais réécrire ma_fonction au sein de Enfant car il faut travailler
sur var2, mais je voudrais aussi qu'en appelant Enfant::ma_fonction() cela
déclenche l'appel de la fonction Parent::ma_fonction() pour effectuer le
travail sur var1.

Je créé Enfant car je veux spécialiser/préciser la classe Parent mais tout
le travail qu'effectue Parent doit etre repporté dans Enfant (ca me parait
normal comme souhait)...

ex:

class Parent
{
protected:
monobjet *var1;


Les données protégées sont habituellement du mauvais design.

public:
void ma_fonction()
{
var1->AutreFonction();
}
};

class Enfant : public Parent
{
protected:
monobjet *var2;
public:
void ma_fonction()
{


Parent::ma_fonction();

var2->AutreFonction();
}
};

//application
void Fonction()
{
Enfant enfant;
enfant.ma_fonction();
//je voudrais que var1->AutreFonction() et var2->AutreFonction() soit
appellée
//car apres tout var1 appartient à enfant
}


Merci de m'expliquer comment établir ce mécanisme,


C'est impossible de le faire automatiquement, à moins de faire quelque chose

class Parent
{
private:
monobject *o;

protected:
virtual void ma_fonction_impl() = 0;

public:
void ma_fonction()
{
o->f();

ma_fonction_impl();
}

};


class Enfant : public Parent
{
private:
monobject *o2;

protected:
void ma_fonction_impl()
{
o2->f();
}
};


int main()
{
Enfant e;
e.ma_fonction(); // appelle Parent::ma_fonction
// qui appelle
// Enfant::ma_fonction_impl()

}

Ceci laisse la place à d'autres classes dérivées. Si tu as plusieurs
couches, tu devras répéter ce système pour chacune.


Jonathan Mcdougall
Montréal, Québec

Avatar
Arnaud Debaene
PurL wrote:

La solution etait au-dessus: ajouter
Parent::AutreFonction();
dans Enfant::ma_fonction().


J'avais pas vu, c'est effectivement une solution pour obtenir le
résultat souhaité mais pas la méthode souhaitée. En effet, je
souhaite quelque chose d'automatique, c'est pas tres efficace de
devoir tout réécrire. Image (et c'est le cas) que j'ai plusieurs
variable à chaque niveau d'héritage et plusieur niveau d'héritage, ca
devient vite l'usine à gaz...
Tu ne dois écrire qu'une seule fois l'appel à la méthode de la classe de

base, dans la méthode de la classe dérivée, et ce pour chaque niveau de ta
hiérarchie. Je ne vois pas d'usine à gaz là dedans : c'est exactement la
même chose quand tu appelles un constucteur avec paramètres de ta classe de
base depuis le constructeur de la classe dérivée (sauf que tu le fais dans
la liste d'initialisation, pas dans le corps du constructeur).

Arnaud