Reputation: 2993
class base {
public:
void virtual fn(int i) {
cout << "base" << endl;
}
};
class der : public base{
public:
void fn(char i) {
cout << "der" << endl;
}
};
int main() {
base* p = new der;
char i = 5;
p->fn(i);
cout << sizeof(base);
return 0;
}
Here signature of function fn defined in base
class is different from signature of function fn()
defined in der
class though function name is same.
Therefore, function defined in der
class hides base
class function fn()
. So class der
version of fn cannot be called by p->fn(i)
call; It is fine.
My point is then why sizeof
class base
or der
is 4
if there is no use of VTABLE pointer? What is requirement of VTABLE pointer here?
Upvotes: 8
Views: 2746
Reputation: 424
The compiler cannot optimize out vtable
member variable out of 'base' class, because there could be another source file within the same or another project which would contain the following:
struct ived : base {
ived() : p(new char[BIG_DATA_SIZE]) {}
virtual ~ived();
virtual void fn(int);
private:
char* p;
};
The destructor and fn
could be implemented somewhere else:
ived::~ived() { delete[] p; }
void ived::fn(int) {
cout << "ived" << endl;
}
And somewhere in another place there could be code like this:
base* object = new ived;
ived->fn(0);
delete object;
cout << sizeof(base) << endl;
So, there would be two problems: virtual function ived::fn
not called, virtual destructor not called, so BIG_DATA_SIZE
not deleted. Otherwise, sizeof(base)
here would be different. That is why compilers always generate vtable
for any class with a virtual member function or a virtual base class.
Regarding calling destructors in derived classes, it must be considered as a must: if you have any class with any virtual function, that class shall also declare a virtual destructor.
Upvotes: 1
Reputation: 92301
The vtable is usually not only used for virtual functions, but it is also used to identify the class type when you do some dynamic_cast
or when the program accesses the type_info
for the class.
If the compiler detects that no virtual functions are ever overridden and none of the other features are used, it just could remove the vtable pointer as an optimization.
Obviously the compiler writer hasn't found it worth the trouble of doing this. Probably because it wouldn't be used very often, and because you can do it yourself by removing the virtual
from the base class.
Upvotes: 1
Reputation: 258618
Inheritance is a is-a
relationship. der
is-a base
. base
has size 4
, der
will have at least size 4
. vftableptr
is a member of base
, it will be a member of der
.
base
has a virtual method, so it will have a pointer to the virtual table, regardless of whether you use it or not.
Upvotes: 0
Reputation: 206566
Note that this is highly implementation dependent & might vary for each compiler.
The requirement for presence of vtable
is that the Base class is meant for Inheritance and extension, and a class deriving from it might override the method.
The two classes Base and Derived might reside in different Translation Unit and the compiler while compiling the Base class won't really know if the method will be overidden or not. So, if it finds the keyword virtual
it generates the vtable
.
Upvotes: 7