I was going through the disadvantages of vtable-based polymorphism.
Vtable Overhead: Each class with virtual functions needs to have a vtable, which contains function pointers to its virtual functions. This can increase the size of the objects and consume additional memory.
Dynamic Cast Overhead: When using dynamic_cast to downcast pointers to derived classes, there is additional runtime overhead for performing type checks.
Object Slicing: When storing derived objects in a container of base class objects, object slicing may occur.
Management of pointers: To prevent object slicing and better manage polymorphic objects, we have to use pointers and that might require heap allocation.
Based on the above disadvantages I was thinking of following design to achieve runtime polymorphism.
class B; class C;
class A{
public:
int common_data1; //common properties
int common_data2;
int type; //type of child stored by the following variant. e.g. 0 for B, 1 for C. we cal also use enum instead of int
std::variant<B,C> child;
void common();
void default_behavior();
void specific()
{
switch(type){
case 0:
std::get<B>(child).specific();
break;
case 1:
std::get<C>(child).specific();
break;
default:
default_behavior();
}
}
};
class B : public A{
public:
int b_data;
void b_fun();
void specific();
};
class C : public B{
public:
int c_data;
void c_fun();
void specific();
};
It seems to eliminate the above disadvantages.
- No Vtable overhead as there are no virtual functions.
- No dynamic cast is required.
- No Object slicing as we are storing the child object in
std::variant
. - Since no slicing occurs, we don't need to use pointers to achieve polymorphism.
Despite the additional overhead associated with employing std::variant
, it appears to offer a superior alternative in comparison to the drawbacks mentioned earlier.
Can C++ experts please guide me regarding this design and provide their deep insights?