Reputation: 8971
I have got:
class A
{
virtual void get();
}
class B: public A
{
void get();
}
class C: public B
{
void get();
}
and
int main()
{
B *i;
i = new C();
i.get();
return (0);
}
if A::get() is virtual:
i.get() calls C::get()
if A::get() is not virtual:
i.get() calls B::get()
My question is:
Why do I not need to put virtual on B::get() to use C::get() with B.get()?
Upvotes: 2
Views: 83
Reputation: 76298
When a member function is declared virtual
in a base class, it will be virtual
for all child classes as well. The fact that you can omit the virtual
keyword in the child classes does not imply it is not virtual.
Your assumption on the code you proposed, that follows:
int main()
{
B* i;
i = new C();
i.get();
return (0);
}
are misguided by the fact that the above code won't even compile (even if you added the semicolons at the end of each class declaration/definition).
When you are dealing with pointers and you want to call a member function you can either dereference the pointer and use the .
operator:
(*ptr).function();
or use the ->
operator:
ptr->function();
Your code does neither of them. But assuming what you actually meant was:
int main()
{
B* i = new C();
i->get();
}
you assumptions turns out to be right:
A::get
is virtual, in i->get
, C::get
will be calledB::get
will be called.Why do I not need to put virtual on
B::get()
to useC::get()
withB.get()
?
You don't. The void get()
member function is virtual from the base class, all the way to the C
class. You don't need to repeat the virtual
keywords, but I'd actually recommend it.
Upvotes: 1
Reputation: 55425
Methods that override virtual methods from the base class will be implicitly virtual, too - that holds for the entire ihneritance chain.
struct A {
virtual int f(int);
};
struct B : A {
int f(int); // overrides A::f, implicitly virtual
void g(float);
};
struct C : B {
int f(int); // overrides B::f, implicitly virtual
int f(char); // doesn't override anything, not virtual
void g(float); // doesn't override and isn't virtual,
// because B::g is not virtual either.
// It hides B::g instead.
};
Upvotes: 4