Consider:
class A
{
public:
virtual void update() = 0;
}
class B : public A
{
public:
void update() { /* stuff goes in here... */ }
private:
double a, b, c;
}
class C {
// Same kind of thing as B, but with different update function/data members
}
I'm now doing:
A * array = new A[1000];
array[0] = new B();
array[1] = new C();
//etc., etc.
If i call sizeof(B)
, the size returned is the size required by the 3 double members, plus some overhead required for the virtual function pointer table. Now, back to my code, it turns out that 'sizeof(myclass)' is 32; that is, I am using 24 bytes for my data members, and 8 bytes for the virtual function table (4 virtual functions). My question is: is there any way I can streamline this? My program will eventually use a heck of a lot of memory, and I don't like the sound of 25% of it being eaten by virtual functions pointers.
Virtual functions require an indirect call through the vtable, which is more expensive than a direct call due to interactions with branch prediction and the instruction cache, and also the prevention of further optimizations which could be carried out after inlining the call.
A virtual call requires at least an extra indexed dereference and sometimes a "fixup" addition, compared to a non-virtual call, which is simply a jump to a compiled-in pointer. Therefore, calling virtual functions is inherently slower than calling non-virtual functions.
Vtables themselves are generally stored in the static data segment, as they are class-specific (vs. object-specific).
vtables are static data per-type; d1 and d2 inherit a vtable-pointer from Parent which points to Derived 's vtable; All vtables point to an offset of 16 (0x10) bytes into the vtable.
The v-table is per class and not per object. Each object contains just a pointer to its v-table. So the overhead per instance is sizeof(pointer)
(usually 4 or 8 bytes). It doesn't matter how many virtual functions you have for the sizeof the class object. Considering this, I think you shouldn't worry too much about it.
Typically, every instance of a class with at least one virtual function will have an extra pointer stored with its explicit data members.
There's no way round this, but remember that (again typically) each virtual function table is shared between all instances of the class, so there is no great overhead to having multiple virtual functions or extra levels of inheritance once you've paid the "vptr tax" (small cost of vtable pointer).
For larger classes the overhead becomes much smaller as a percentage.
If you want functionality that does something like what virtual functions do, you are going to have to pay for it in some way. Actually using native virtual functions may well be the cheapest option.
The space cost of a vtable is one pointer (modulo alignment). The table itself is not placed into each instance of the class.
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