C ++虚拟+受保护?

时间:2010-12-30 12:43:16

标签: c++ class virtual protected

在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

5 个答案:

答案 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的子类。