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;
}
...
};