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.
精彩评论