I'm having trouble understanding what the purpose of the virtual
keyword in C++. I know C and Java very well but I'm new to C++
From wikipedia
In object-oriented programming, a virtual function or virtual method is a function or method whose behavior can be overridden within an inheriting class by a function with the same signature.
However I can override a method as seen below without using the virtual
keyword
#include <iostream>
using namespace std;
class A {
public:
int a();
};
int A::a() {
return 1;
}
class B : A {
public:
int a();
};
int B::a() {
return 2;
}
int main() {
B b;
cout << b.a() << endl;
return 0;
}
//output: 2
As you can see below, the function A::a is successfully overridden with B::a without requiring virtual
Compounding my confusion is this statement about virtual destructors, also from wikipedia
as illustrated in the following example, it is important for a C++ base class to have a virtual destructor to ensure that the destructor from the most derived class will always be called.
So virtual
also tells the compiler to call up the parent's destructors? This seems to be very different from my original understanding of virtual
as "make the function overridable"
Make the following changes and you will see why:
#include <iostream>
using namespace std;
class A {
public:
int a();
};
int A::a() {
return 1;
}
class B : public A { // Notice public added here
public:
int a();
};
int B::a() {
return 2;
}
int main() {
A* b = new B(); // Notice we are using a base class pointer here
cout << b->a() << endl; // This will print 1 instead of 2
delete b; // Added delete to free b
return 0;
}
Now, to make it work like you intended:
#include <iostream>
using namespace std;
class A {
public:
virtual int a(); // Notice virtual added here
};
int A::a() {
return 1;
}
class B : public A { // Notice public added here
public:
virtual int a(); // Notice virtual added here, but not necessary in C++
};
int B::a() {
return 2;
}
int main() {
A* b = new B(); // Notice we are using a base class pointer here
cout << b->a() << endl; // This will print 2 as intended
delete b; // Added delete to free b
return 0;
}
The note that you've included about virtual destructors is exactly right. In your sample there is nothing that needs to be cleaned-up, but say that both A and B had destructors. If they aren't marked virtual, which one is going to get called with the base class pointer? Hint: It will work exactly the same as the a() method did when it was not marked virtual.
You could think of it as follows.
All functions in Java are virtual. If you have a class with a function, and you override that function in a derived class, it will be called, no matter the declared type of the variable you use to call it.
In C++, on the other hand, it won't necessarily be called.
If you have a base class Base and a derived class Derived, and they both have a non-virtual function in them named 'foo', then
Base * base;
Derived *derived;
base->foo(); // calls Base::foo
derived->foo(); // calls Derived::foo
If foo is virtual, then both call Derived::foo.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With