在C ++中,我有一个基类A,一个子类B.它们都有虚拟方法Visit。 我想在B中重新定义“访问”,但是B需要访问每个A(以及所有子类)的“访问”功能。
我有类似的东西,但它告诉我B不能访问A的受保护成员!但B也是A :-P
那么,我该怎么办?
class A
{
protected:
virtual Visit(...);
}
class B : public class A
{
protected:
vector<A*> childs;
Visit(...);
}
B::Visit(...)
{
foreach(A* a in childs)
{
a->Visit(...);
}
}
THX
答案 0 :(得分:9)
您可以使用自己的对象访问受保护的成员,但是您可能无法使用替代对象访问受保护的成员,除非它也属于您的类(不仅仅是基类)。
有一种解决方法,就像有一种解决方法,友谊不被继承。
在这个例子的任何情况下:
class A
{
protected:
virtual void Visit(...);
void visitOther( A& other, ... )
{
other.Visit(...);
}
};
class B : public A
{
Visit(...);
vector<A*> childs;
};
B::Visit(...)
{
BOOST_FOREACH( a, childs )
{
visitOther( *a, ... );
}
}
答案 1 :(得分:1)
让B成为A的朋友:
class A
{
protected:
virtual void Visit();
friend class B;
};
class B : public A
{
protected:
virtual void Visit();
};
答案 2 :(得分:1)
虚拟功能的本质正是您要逃避的。 这里
foreach (A * in the Childs)
{
a-> Visit (...);
}
所有a
都会调用相应的访问功能。
没有必要从A公开派生,你应该使用protected。
在A
中,Visit函数不是虚拟的,并且是受保护的构造函数,
通过inheratinance(以及朋友和hax)限制实例化。
如果您了解更多详情,我们也可以提供更多帮助。
编辑1:如果您正在玩虚拟游戏,请不要忘记虚拟析构函数。
编辑2:试试这个:
foreach (A * in the Childs)
{
a->A::Visit(...);
}
答案 3 :(得分:1)
听编译器告诉你你的设计被搞砸了,不要再假装你知道了。公开访问。更好的是,让它成为非虚拟的:
struct A {
void Visit() { impl_visit(); }
private:
virtual void impl_visit();
};
struct B : A {
private:
Vector<A*> childs;
void impl_visit() {
...
foreach child in childs child->Visit();
...
}
};
哦,当你正在请求委员会添加漂亮的“foreach / in”语法时。 [我很认真,他们正在寻找使C ++更易于使用的方法!]
答案 4 :(得分:0)
在“示例”中进行了更正。现在B是A的子类。