Reputation: 189
I have the following code:
#include<iostream>
using namespace std;
struct Base{
void f(int x){
cout<<"B";
}
};
struct Derived: public Base {
virtual void f(double x){
cout<<"D";
}
};
int main(){
Derived d;
int x = 5;
d.f(x);
Base *pb = &d;
pb->f(x);
}
It outputs: DB
Even though pb stores the pointer to the derived class. Why is the method of
Base
class getting called?
Upvotes: 1
Views: 88
Reputation: 123114
Declaring Derived::f
virtual doesn't make Base::f
virtual, hence when you call f
on a pointer to Base
then Base::f
is called.
You should declare the method virtual
in Base
. It will then be also virtual
in Derived
, you don't need to repeat virtual
there. In Derived
you should use the override
specifier like this:
struct Base{
virtual void f(int x){
cout<<"B";
}
};
struct Derived: public Base {
void f(double x) override {
cout<<"D";
}
};
The override
specifier helps to catch mistakes when the method does not actually override
an inherited method. For example for the above you will get an error along the line of:
source>:10:10: error: 'void Derived::f(double)' marked 'override', but does not override
10 | void f(double x) override {
| ^
The parameter types must match when you want to override.
This code prints the expected DD
:
#include <iostream>
struct Base {
virtual void f(int x){
std::cout << "B";
}
};
struct Derived: public Base {
void f(int x) override {
std::cout << "D";
}
};
Note that if you don't use override
then such mistakes can go unnoticed. When the classes are defined like this:
struct Base{
virtual void f(int x){
std::cout<<"B";
}
};
struct Derived: public Base {
void f(double x) {
std::cout<<"D";
}
};
Then Derived::f
does not override Base::f
. It only hides it and the output would still be DB
.
Upvotes: 2
Reputation: 295
It prints D first because of your function call of derived class and then it prints B because you are simply calling the function of base class
Upvotes: -1