Reputation: 295
class base
{
public:
virtual void showbase() {
// ----------
}
};
class base1 {
public:
virtual void showbase1() {
// -------
}
};
class derived : public base, public base1
{
void showbase() {
// ----
}
void showbase1() {
// -------
}
};
int main()
{
base* p = new derived();
p->showbase1();
base1* p1 = new derived();
p1->showbase();
}
As per my understanding about virtual function is that compiler deals it with run time (vtable mechanism), then why I am getting compile time error.
Upvotes: 1
Views: 133
Reputation: 88215
As per my understanding about virtual function is that compiler deals it with run time (vtable mechanism), then why I am getting compile time error.
"Deals with it" is pretty vague and vtables are not magic; In C++ virtual dispatch allows for the actual function called to be one that overrides the statically declared virtual function. That means that the function which is being overridden must be known at compile time.
The vtable does not contain information that would be necessary to look up functions at run-time. Instead, it's basically just a list of pointers to overriding functions. The base provides a complete list of its virtual functions and so, given a particular base type, the compiler knows at compile-time where to go in the vtable for that base for a particular function override; The compiler can generate code that goes directly to that spot in the vtable, gets the pointer, and calls the overriding function.
Then, at run-time, when the actual object of derived type is created, the derived object's constructor fills in the base's vtable, so that anything checking the vtable will get pointers to the derived type's functions.
So the problem with your code is that the function you're calling, showbase()
, is not on the list of virtual functions for the type the compiler knows you're accessing, base1
; The compiler can't know where in base1's
vtable to get a pointer for a function override named showbase()
, because there is no such entry in base1
's vtable.
Upvotes: 1
Reputation: 2397
p'static type s type is base and hence you can only call with it functions that have been definied into base even if at the end, it will be the functions from derived which will be called because p's dynamic type is derived
Same thing happens for p1.
Maybe you meant p->showbase();
and p1->showbase1();
Upvotes: 0
Reputation: 3511
Your base class(es) only know about their own member functions, so you can't use it this way. You could do this instead:
base* p = new derived();
p->showbase();
base1* p1 = new derived();
p1->showbase1();
To answer your question about runtime polymorphism, it is dealing with runtime polymorphism (late binding) via the vtable, as you say. But with multiple inheritance, there is essentially a vtable for for each base class. You can't access one base class' vtable via a pointer to the other base class.
Upvotes: 1
Reputation: 101476
To simulate a compiler, consider what a compiler sees:
class base
{
public:
virtual void showbase() {
// ----------
}
};
base* p = /*blah blah*/;
p->showbase1();
Yes, base
is a polymorphic class. And p
is indeed a pointer-tobase
. But since p
points just to a base
, and importantly not to a base1
(where showbase1
lives) the compiler interprets the above code like this. Obviously, I'm paraphrasing:
Here is a class named `base` with a single virtual method called `showbase`. Here is a pointer to a `base` object. Call the method named `showbase1`
And the compiler complains:
Um, excuse me buddy, but
base
doesn't have a method calledshowbase1
.
You asked:
[My] understanding about virtual function is that compiler deals with it at run time. Why I am getting compile time error?
Because the code you've written is nonsense. Here basically is how polymorphism works.
But what you are trying to do is:
Upvotes: 2
Reputation: 3324
A base class pointer to a derived class can only access the member functions defined in the base class. It is illegal to try and access other functions defined in the derived class through it. In your case base
class does not define showbase1
and therefore this is illegal
base* p = new derived();
p->showbase1(); //illegal
However, you can do this:
p->showbase(); // legal because showbase is a member function of base
Similarly you can't access showbase1
using a base
class pointer
base1* p1 = new derived();
p1->showbase(); //illegal
p1->showbase1(); //legal
Upvotes: 1