What is the purpose of using the reserved word virtual in front of functions? If I want a child class to override a parent function, I just declare the same function such as void draw(){}
.
class Parent {
public:
void say() {
std::cout << "1";
}
};
class Child : public Parent {
public:
void say()
{
std::cout << "2";
}
};
int main()
{
Child* a = new Child();
a->say();
return 0;
}
The output is 2.
So again, why would the reserved word virtual
be necessary in the header of say()
?
Thanks a bunch.
This is a very important aspect of c++ programming-- almost every interview I've been to, I get asked this question.
What happens if you change your main to:
Also, it's worth understanding what a vtable is.
Try it with:
Without
virtual
, both with print '1'. Add virtual, and the child will act like a Child, even though it's being referred to via a pointer to aParent
.When you use the keyword virtual, a virtual function table is created to locate the correct methods in an instance. Then, even if the derived instance is pointed to by a base class pointer, it will still find the correct implementation of the method.
Well I tested it for myself, because there are a lot of things we can think about:
output:
I think that a good, simple and short answer might look like this (because I think people who can understand more can memorize less thus needing for short and simple explanation):
Virtual methods checks for the DATA of the instance the pointer points to, while classic methods don't thus calling the method correponding to the specified type.
The point of that feature is the following: suppose you have an array of A's. The array can contain B's, C's, (or even derived types.). if you want to sequentially call the same method of all those instances, you would call each one you overloaded.
I find this quite tricky to understand, and obviously any C++ course should explained how this is achieved, because most of the time you are just teached about virtual functions, you use them, but until you understand how the compiler understand them and how the executable will handle the calls, you are in the dark.
The thing about VFtables is that I have never been explained what kind of code it adds, and that's obviously here where C++ requires much more experience than C, and this might be the main reason C++ was labelled as "slow" in its early days: in fact, it's powerful, but just like everything, it's powerful if you know how to use it, or else you just "blow your whole leg off".
This is the classic question of how polymorphism works I think. The main idea is that you want to abstract the specific type for each object. In other words: You want to be able to call the Child instances without knowing it's a child!
Here is an example: Assuming you have class "Child" and class "Child2" and "Child3" you want to be able to refer to them through their base class (Parent).
As you can imagine, this is very powerful. It let's you extend the Parent as many times as you want and functions that take a Parent pointer will still work. For this to work as others mention you need to declare the method as virtual.
If you do not use the
virtual
keyword you are not overriding, but rahter defining an unrelated method in the derived class that will hide the base class method. That is, without thevirtual
,Base::say
andDerived::say
are unrelated --besides the name coincidence.When you use the virtual keyword (required in the base, optional in the derived class), you are telling the compiler that classes that derive from this base will be able to override the method. In that case,
Base::say
andDerived::say
are considered overrides of the same method.When you use a reference or pointer to a base class to call a virtual method, the compiler will add the appropriate code so that the final overrider is called (the override in the most derived class that defines the method in the hierarchy of the concrete instance in use). Note that if you do not use references/pointer but local variables, the compiler can resolve the call and it does not need to use the virtual dispatch mechanism.