C++ C+中静态成员的多态性与遗传+;

C++ C+中静态成员的多态性与遗传+;,c++,inheritance,static,C++,Inheritance,Static,我需要为每个班级保留一个孩子的列表(向量),我有一个棘手的问题: 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: p

我需要为每个班级保留一个孩子的列表(向量),我有一个棘手的问题:

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();
}
A类
{
受保护的:
INTA;
静态向量儿童;
公众:
A(inta):A(A){;};
虚拟无效添加到儿童(A*obj);
虚拟void ShowChildren();
虚拟虚空显示();
};
B类:公共A
{
受保护的:
int b;
静态向量儿童;
公众:
B(inta,intb):B(B),a(a){a::AddToChildren(this);};
虚拟虚空显示();
};
丙类:公共乙类
{
受保护的:
INTC;
公众:
C(inta,intb,intc):C(C),b(a,b){b::AddToChildren(this);};
虚拟虚空显示();
};
向量A::children=vector();
向量B::children=vector();
void A::AddToChildren(A*obj)
{
儿童。推回(obj);
}
void A::ShowChildren()
{
for(vector::iterator i=children.begin();i!=children.end();i++)
(*i)->Show();
}
添加A(0)、B(1,1)和C(2,2,2)并调用A.ShowChildren给出:1,1;2,2,2 ; 2,2,2

每次我创建类C的实例时,都会更新A::children,而不是B::children和A::children。所以。。。类C被两次添加到类的子类,但没有添加到类B。当我将AddChildren类(字面上的复制)复制到类B时,它会有所帮助,这样每个类都有自己的AddChildren/ShowChildren。我也用指针完成了这个任务,但我想知道有没有更好的方法。我认为问题在于“使用正确的向量”,但我不知道如何强制编译器使用正确的向量

对于我在这里做错了什么,如果有任何建议,我将不胜感激

首先,感谢大家的评论和帮助。使用您的建议(关于我的设计和虚拟GetList()),我设法简化了我的程序:

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;
}
A类
{
受保护的:
INTA;
虚拟向量*GetList();
公众:
A(inta):A(A){;};
A(inta,A*继承):A(A){AddToChildren(继承);};
静态向量儿童;
虚拟无效添加到儿童(A*obj);
虚拟void ShowChildren();
虚拟虚空显示();
};
B类:公共A
{
受保护的:
int b;
虚拟向量*GetList();
公众:
静态向量儿童;
B(inta,intb):B(B),a(a,this){;};
B(inta,intb,a*继承):B(B),a(a,this){AddToChildren(继承);};
虚拟虚空显示();
};
丙类:公共乙类
{
受保护的:
INTC;
公众:
C(inta,intb,intc):C(C),b(a,b,this){};
虚拟虚空显示();
虚拟向量*GetList();
};
向量A::children=vector();
向量B::children=vector();
void A::AddToChildren(A*obj)
{
GetList()->推回(obj);
}
void A::ShowChildren()
{
对于(向量::迭代器i=GetList()->begin();i!=GetList()->end();i++)
(*i)->Show();
}
向量*A::GetList()
{
回归与儿童;
}
向量*B::GetList()
{
回归与儿童;
}
vector*C::GetList()
{
回归与儿童;
}
现在它使用构造函数而不调用上层类,它只调用上层类的适当构造函数。这不是最好的,但我觉得更好


再次感谢大家的帮助

编辑:讽刺地指出,这不适用于您发布的案例。我不删除它,因为它在其他情况下可能有用

当您调用AddToChildren()时,您将得到A的实现,它(当然)将添加到A的静态成员

<>这是因为C++没有“虚拟数据”的概念。一种方法是添加一个名为GetList()的虚拟函数。I它看起来像这样(未经测试的代码):


编辑:讽刺地指出,这不适用于您发布的案例。我不删除它,因为它在其他情况下可能有用

当您调用AddToChildren()时,您将得到A的实现,它(当然)将添加到A的静态成员

<>这是因为C++没有“虚拟数据”的概念。一种方法是添加一个名为GetList()的虚拟函数。I它看起来像这样(未经测试的代码):


函数的代码仅适用于定义它的类,即使它是虚拟的。因此,以下函数始终应用于类
A
,因此附加到
A::children

void A::AddToChildren(A *obj)
{
  children.push_back(obj);
}
如果您希望每个类都有不同的向量,那么您别无选择,只能将代码从一个类重复到另一个类(静态变量、其初始化以及add to children函数或get children list函数)。不过,我建议不要在构造函数中调用虚拟函数

您可能感兴趣的另一种方法是为此类存储提供一个独特的类模板:

template<typename T> struct children 
{
  static std::vector<T*> list;
  static void add(T* t) { list.push_back(t); }
};

B::B() : A() {
  children<A>::add(this);
}

C::C() : B() {
  children<B>::add(this);
}
模板结构子项
{
静态std::向量列表;
静态void add(T*T){list.push_back(T);}
};
B::B():A(){
儿童::添加(这个);
}
C::C():B(){
儿童::添加(这个);
}

函数的代码仅适用于定义它的类,即使它是虚拟的。因此,以下函数始终应用于类
A
,因此附加到
A::children

void A::AddToChildren(A *obj)
{
  children.push_back(obj);
}
如果您希望每个类都有不同的向量,那么您别无选择,只能将代码从一个类重复到另一个类(静态变量、其初始化以及add to children函数或get children list函数)。不过,我建议不要在构造函数中调用虚拟函数

您可能感兴趣的另一种方法是为此类存储提供一个独特的类模板:

template<typename T> struct children 
{
  static std::vector<T*> list;
  static void add(T* t) { list.push_back(t); }
};

B::B() : A() {
  children<A>::add(this);
}

C::C() : B() {
  children<B>::add(this);
}
模板结构子项
{
静态std::向量列表;
静态void add(T*T){list.push_back(T);}
};
B::B():A(){
儿童::添加(这个);
}
C::C():B(){
儿童::添加(这个);
}

>

@ Neli:这种方法不能解决这个具体的问题,因为在C++中,从析构函数/构造函数调用虚函数实际上不是虚函数。因此,从构造函数中,GetList()仍将返回A的子级

另外,这应该是对回复的评论,但我找不到
template<typename T> struct children 
{
  static std::vector<T*> list;
  static void add(T* t) { list.push_back(t); }
};

B::B() : A() {
  children<A>::add(this);
}

C::C() : B() {
  children<B>::add(this);
}
class A
{
    ...
    virtual vector<A*> * ChildrenPtr();
};

...

A::ChildrenPtr() {return &A::children;}
B::ChildrenPtr() {return &B::children;}
C::ChildrenPtr() {return NULL;}

void A::AddToChildren(A *obj)
{
    vector<A*>  * pChildren = ChildrenPtr();
    if (pChildren)
        pChildren->push_back(obj);
}
class A {
  ...
  int a;
  static vector<A*> children;
  ...
  A(int a) : a(a) {}

  virtual vector<A*> *GetList() = 0;

  void AddToChildren(A* obj) { // note: non-virtual
    GetList()->push_back(obj);
  }
  ...
};

class B : public A {
  ...
  int b;
  static vector<A*> children;
  ...
  B(int a, int b) : b(b), A(a) { 
    AddToChildren(this);
  }

  virtual vector<A*> *GetList() {
    return &A::children;
  }
  ...
};

class C : public B {
  ...
  int c;
  ...
  C(int a, int b, int c) : c(c), B(a,b) { 
    AddToChildren(this);
  };    

  virtual vector<A*> *GetList() {
    return &B::children;
  }
  ...
};