OVH Cloud OVH Cloud

pb sur l'héritage

6 réponses
Avatar
KooK
Bonjour,

Voilà mon pb, je veux passer au constructeur de A un pointeur sur un
objet créer dans celui de B. Comment faire ?

class A{
classZ *qqc;
classY *autre_chose;
public :
A(classZ*, classY*=NULL, int=0);
};

class B : public A{
...
B(classZ z, int a) : A(z, ?, a){
classY y = new classY(...);
}
};

Je voudrais donc que y remplace le '?' comment organiser mon code ?

KooK

6 réponses

Avatar
Rémy
"KooK" a écrit dans le message de news:
450910be$0$31322$
Bonjour,

Voilà mon pb, je veux passer au constructeur de A un pointeur sur un objet
créer dans celui de B. Comment faire ?

class A{
classZ *qqc;
classY *autre_chose;
public :
A(classZ*, classY*=NULL, int=0);
};

class B : public A{
...
B(classZ z, int a) : A(z, ?, a){
classY y = new classY(...);
}
};

Je voudrais donc que y remplace le '?' comment organiser mon code ?

KooK


Ajouter à A une méthode SetY et dans le constructeur de B faire
B(classZ z, int a) : A(z, NULL, a){
...
classY y = new classY(...);
SetY(y);
}

Avatar
Michel Decima
Bonjour,

Voilà mon pb, je veux passer au constructeur de A un pointeur sur un
objet créer dans celui de B. Comment faire ?

class A{
classZ *qqc;
classY *autre_chose;
public :
A(classZ*, classY*=NULL, int=0);
};

class B : public A{
...
B(classZ z, int a) : A(z, ?, a){
classY y = new classY(...);
}
};

Je voudrais donc que y remplace le '?' comment organiser mon code ?


je dirais bien

B::B(classZ z, int a) : A(z, new classY(...), a) {}

mais je pense que ce n'est pas ce que tu cherche.

S'il s'agit d'initialiser une classe de base avec un membre de la classe
derivee, il y a une astuce classique qui utilise une classe
intermediaire et l'ordre des initialisations lors d'un heritage
multiple. En gros, ca donne ca:


class B_base
{
protected:
classY* y;
B_base(...) : y(new classY(...)) {}
};

class B : public B_base, public A
{
public:
B(classZ z, int a)
: B_base(...)
, A(z, y, a)
{}
};

Tu a la garantie que y est initialise correctement lorsqu'il est passe
au constructeur de A parce que le constructeur de B_base aura ete appele
avant.

Pour se faciliter la vie, on trouve une implementation de l'idiome chez
boost, ca doit s'appeler base_from_member. 'e crois qu'on trouve aussi
le nom de "Ron's member" dans la litterature pour designer cet idiome).

Avatar
Michel Decima

Ajouter à A une méthode SetY et dans le constructeur de B faire
B(classZ z, int a) : A(z, NULL, a){
...
classY y = new classY(...);
SetY(y);
}


Si le constructeur de A exige un parametre non NULL, ca ne marche pas.
Et si on ne peut pas modifier A (pour ajouter le setter), ca ne marche
pas non plus.

Avatar
KooK
Bonjour,

Voilà mon pb, je veux passer au constructeur de A un pointeur sur un
objet créer dans celui de B. Comment faire ?

class A{
classZ *qqc;
classY *autre_chose;
public :
A(classZ*, classY*=NULL, int=0);
};

class B : public A{
...
B(classZ z, int a) : A(z, ?, a){
classY y = new classY(...);
}
};

Je voudrais donc que y remplace le '?' comment organiser mon code ?


je dirais bien

B::B(classZ z, int a) : A(z, new classY(...), a) {}

mais je pense que ce n'est pas ce que tu cherche.

S'il s'agit d'initialiser une classe de base avec un membre de la classe
derivee, il y a une astuce classique qui utilise une classe
intermediaire et l'ordre des initialisations lors d'un heritage
multiple. En gros, ca donne ca:


class B_base
{
protected:
classY* y;
B_base(...) : y(new classY(...)) {}
};

class B : public B_base, public A
{
public:
B(classZ z, int a)
: B_base(...)
, A(z, y, a)
{}
};

Tu a la garantie que y est initialise correctement lorsqu'il est passe
au constructeur de A parce que le constructeur de B_base aura ete appele
avant.

Pour se faciliter la vie, on trouve une implementation de l'idiome chez
boost, ca doit s'appeler base_from_member. 'e crois qu'on trouve aussi
le nom de "Ron's member" dans la litterature pour designer cet idiome).


Ok merci je vais essayer ça car effectivement, je ne peux pas toucher à

la classe A qui appartient à une bibliothèque.

Merci


Avatar
kanze
Michel Decima wrote:

[...]
S'il s'agit d'initialiser une classe de base avec un membre de
la classe derivee, il y a une astuce classique qui utilise une
classe intermediaire et l'ordre des initialisations lors d'un
heritage multiple. En gros, ca donne ca:

class B_base
{
protected:
classY* y;
B_base(...) : y(new classY(...)) {}
};

class B : public B_base, public A
^^^^^^


Pourquoi public, et non private ?? C'est plutôt un détail de
l'implémentation, non ?

--
James Kanze GABI Software
Conseils en informatique orientée objet/
Beratung in objektorientierter Datenverarbeitung
9 place Sémard, 78210 St.-Cyr-l'École, France, +33 (0)1 30 23 00 34

Avatar
Michel Decima
kanze wrote:
Michel Decima wrote:

class B_base
{
protected:
classY* y;
B_base(...) : y(new classY(...)) {}
};

class B : public B_base, public A
^^^^^^


Pourquoi public, et non private ?? C'est plutôt un détail de
l'implémentation, non ?


Oups, c'est bien sur private et pas public (manque de rigueur au bout
des doigts). Coincidence, j'ai du utiliser cet idiome cet apres-midi,
avec une derivation private ;)