开发者

C++ virtual + protected?

In C++, I have a base class A, a sub class B. Both have the virtual method Visit. I would like to redefine 'Visit' in B, but B need to access the 'Visit' function of each A (and all subclass to).

I have something like that, but it tell me that B cannot access the protected member of A! But B is a A too :-P

So, what can I do?

class A
{
protected:
virtual Visit(...);
}

class B : public class A
{
protected:
vector<A*> childs;
Visit(..开发者_Go百科.);
}

B::Visit(...)
{
 foreach(A* a in childs)
 {
   a->Visit(...);
 }
}

Thx


You may access a protected member using your own object but you may not access a protected member using an alternative object unless it is also of your class (not simply the base class).

There is a workaround, just as there is a workaround with friendship not being inherited.

In any case with this example:

class A
{
protected:
  virtual void Visit(...);

  void visitOther( A& other, ... )
  {
     other.Visit(...);
  }
};



class B : public A
   {
       Visit(...);
       vector<A*> childs;
   };
       
   B::Visit(...)
    {
     for( auto a : childs )
     {
         visitOther( *a, ... );
     }
   }


just make B a friend of A :

class A  
{  
protected:  
    virtual void Visit();  
    friend class B;  
}; 

class B : public A  
{  
protected:  
    virtual void Visit();  
};


A virtual function's essence is exactly which you are escaping from. Here

foreach (A * in the Childs)
{
  a-> Visit (...);
}

all a will call it's corresponding Visit function.

It is unnecessary to publicly derive from A, you should use protected.

In A the Visit function is not virtual, and make a protected constructor, to restrict instantiation through inheratinance (and friends, and hax).

If you tell more details, we can also help more.

EDIT 1: if you are playing with virtuals, do not forget virtual destructors.

EDIT 2: try this:

foreach (A * in the Childs)
{
  a->A::Visit(...);
}


Listen to the compiler telling you your design is screwed and stop pretending you know better. Make Visit public. Better still, make it non-virtual:

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

Oh and while you're at it petition the Committee to add the nice "foreach/in" syntax. [I'm serious, they're looking for ways to make C++ easier to use!]


It is corrected in the "example". Now B is subclass of A.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜