Reputation: 23
Here if I leave class B as empty then total how many vtables will be created here ?
#include <bits/stdc++.h>
using namespace std;
class A{
public:
virtual void display(){
cout<<"A Class"<<endl;
}
};
class B: public A{
public:
};
int main()
{
A *ob = new B();
ob->display();//A Class
return 0;
}
I was assuming still 2 vtable will be created one in A and 1 in B but for Class B it will be empty and as per design of c++ if we call display function then if it doesn't find the function in its vtable then it will look for the vtable in parent class and will set the binding of that function with vptr but, I am not sure of that.
Can anybody explain with the exact concept
I tired finding the answer over the internet but, didn't get the desired answer
Upvotes: 1
Views: 74
Reputation: 275730
Practically B
needs some run time type information, which is typically stored as part of the "vtable" , that is distinct from A
.
This is because:
bool test(A* a) {
return dynamic_cast<B*>(a);
}
has to behave differently if we pass a pointer-to-B
or a pointer-to-A
.
A "typical" way to implement vtables in C++ looks like this:
using vfunc = void(*)(void*);
template<auto creator>
static auto const* get_vtable() {
static const auto table = creator();
return &table;
}
struct A_vtable {
void const* rtti;
void(*display)(void*);
};
A_vtable create_A_vtable_A() {
return {
"This is class A!",
[](void* self) {
std::cout<<"A Class"<<std::endl;
}
};
}
struct A {
A_vtable const* vtable;
A():vtable(get_vtable<&create_A_vtable_A>()) {}
};
struct B_vtable:A_vtable {
};
B_vtable create_B_vtable_B() {
B_vtable vtable = create_A_vtable_A;
vtable.rtti = "This is class B!";
}
struct B:A {
B() {
vtable = get_vtable<&create_B_vtable_B>();
}
};
with the note that my runtime type information is intentionally a joke.
That RTTI information in a real situation will tell you how what the runtime type is, and how to get a pointer to the most-derived type. Here I just store a void pointer to a string.
But you'll notice I moved the vtable
pointer to a different table in the constructor of B
. This is basically how compilers do it (the standard gives compilers lots of freedom, so you cannot assume it looks anything at all like the above, it might not even have a vtable).
Upvotes: 1