que je dois garder une liste (vecteur) des enfants pour chaque classe, et j'ai un problème délicat:Polymorphisme et l'héritage des membres statiques en C++
class A
{
protected:
int a;
static vector<A*> children;
public:
A(int a): a(a) {;};
virtual void AddToChildren(A* obj);
virtual void ShowChildren();
virtual void Show();
};
class B: public A
{
protected:
int b;
static vector<A*> children;
public:
B(int a, int b): b(b), A(a) { A::AddToChildren(this);};
virtual void Show();
};
class C: public B
{
protected:
int c;
public:
C(int a, int b, int c): c(c), B(a,b) { B::AddToChildren(this);};
virtual void Show();
};
vector<A*> A::children=vector<A*>();
vector<A*> B::children=vector<A*>();
void A::AddToChildren(A *obj)
{
children.push_back(obj);
}
void A::ShowChildren()
{
for(vector<A*>::iterator i=children.begin(); i!=children.end();i++)
(*i)->Show();
}
Ajout A (0), B (1,1) et C (2,2,2) et appelant a.ShowChildren donne: 1,1; 2,2,2; 2,2,2
Chaque fois que je crée une instance de classe C, A :: children est mis à jour à la place de B :: children et A :: children. Sooo ... la classe C est ajoutée deux fois aux enfants de classe A, mais pas ajoutée à la classe B. Cela aide quand je copie la classe AddChildren (littéralement copie) à la classe B, de sorte que chaque classe ait ses propres AddChildren/ShowChildren. J'ai également réussi à accomplir cette tâche en utilisant des pointeurs, mais je me demande s'il y a un meilleur moyen. Je pense que le problème est quelque part dans "l'utilisation du bon vecteur", mais je ne sais pas comment forcer le compilateur à utiliser le bon.
Je serais reconnaissant pour toute suggestion sur ce que je fais mal ici. Tout d'abord, merci à tous pour vos commentaires et votre aide. En utilisant vos conseils (au sujet de ma conception et GetList virtuelle()) J'ai réussi à simplifier mon programme:
class A
{
protected:
int a;
virtual vector<A*>* GetList();
public:
A(int a): a(a) {;};
A(int a, A* inherited):a(a) { AddToChildren(inherited);};
static vector<A*> children;
virtual void AddToChildren(A* obj);
virtual void ShowChildren();
virtual void Show();
};
class B: public A
{
protected:
int b;
virtual vector<A*>* GetList();
public:
static vector<A*> children;
B(int a, int b): b(b), A(a,this){;};
B(int a, int b, A* inherited) : b(b), A(a,this){AddToChildren(inherited);};
virtual void Show();
};
class C: public B
{
protected:
int c;
public:
C(int a, int b, int c): c(c), B(a,b,this) { };
virtual void Show();
virtual vector<A*>* GetList();
};
vector<A*> A::children=vector<A*>();
vector<A*> B::children=vector<A*>();
void A::AddToChildren(A *obj)
{
GetList()->push_back(obj);
}
void A::ShowChildren()
{
for(vector<A*>::iterator i=GetList()->begin(); i!=GetList()->end();i++)
(*i)->Show();
}
vector<A*> * A::GetList()
{
return & children;
}
vector<A*> * B::GetList()
{
return & children;
}
vector<A*> * C::GetList()
{
return & children;
}
Maintenant, ses constructeurs en utilisant sans appeler la classe supérieure, il appelle juste le constructeur proprement dit de la classe supérieure. Ce n'est pas le meilleur, mais je pense que c'est mieux.
Une fois de plus, merci à tous pour votre aide.
Hmm, cela peut sembler un peu flou. C n'a pas de liste d'enfants car c'est une "feuille", c'est la classe du bas. L'intention était que chaque classe descendante s'ajoute aux listes "Enfants" de toutes les classes dont elle hérite. Donc C devrait être ajouté à A :: children et B :: children. Dans la question il y a une version mise à jour, j'ai fait travailler mon design avec la proposition de Neil. Je pense que tu as raison à propos de ma conception de classe. Le changer a rendu la chose un peu plus simple (mais pas encore le meilleur je pense). – mcmil