-3

What are the conditions when class becomes polymorphic? 1. Is it polymorphic if it is inherited and none of the method is overriden but only if they have virtual keyword in signature? 2. Is it polymorphic if there is no inheritance and methods are declared virtual?

Does it create VTable in above cases?

debonair
  • 2,505
  • 4
  • 33
  • 73
  • 2
    You may find http://en.cppreference.com/w/cpp/types/is_polymorphic and http://en.cppreference.com/w/cpp/language/object#Polymorphic_objects interesting. – François Andrieux Nov 02 '17 at 17:18
  • @FrançoisAndrieux and it creates VTable always if its polymorphic? – debonair Nov 02 '17 at 17:22
  • Please read the links. From the second one : *"Within each polymorphic object, the implementation stores additional information (in every existing implementation, it is one pointer unless optimized out), which is used by virtual function calls and by the RTTI features..."* – François Andrieux Nov 02 '17 at 17:25
  • [If you are ever unsure `std::is_polymorphic` can help you out.](http://en.cppreference.com/w/cpp/types/is_polymorphic) – user4581301 Nov 02 '17 at 17:52
  • 1
    V-table is a possible implementation. – Jarod42 Nov 02 '17 at 18:01
  • 1
    The interesting question here is can If the compiler can prove it's never used, can the As-If rule kick in and remove the virtualization book keeping? – user4581301 Nov 02 '17 at 18:08
  • 1
    @user4581301 yes, the method is called devirtualization and there is extensive research in this field – bolov Nov 02 '17 at 18:13
  • @bolov thank you very much. Reading up on devirtualization added to the todo list. – user4581301 Nov 02 '17 at 18:19

1 Answers1

5

A class is polymorphic if it has at least one virtual method (of its own or inherited).


When does it create VTable?

Ok so first let's get the elefant out of the room. The standard doesn't require Virtual Tables and intentionally leaves open the method of implementing dynamic polymorphism. In this case it just defines rules of behavior, but doesn't mandate any method of implementing said behavior. See Alternatives to vtable , Alternative virtual mechanism implementations? or Comparison with alternatives. They are an interesting read. Now that the elephant is out of the room in practice most of (if not all of) C++ compilers implement polymorphism through the vtables mechanism.

A polymorphic class will have a virtual table. And the discussion could easily end here.


However there is an interesting (mostly academic) case to consider: virtual inheritance without polymorphic objects.

E.g.:

struct A {};
struct B : virtual A {};
struct C : virtual A {};

struct X : B, C { };

None of the above classes(*) are polymorphic. I.e.

static_assert(!std::is_polymorphic<B>::value);
static_assert(!std::is_polymorphic<C>::value);
static_assert(!std::is_polymorphic<X>::value);

because we don't have any virtual methods.

The question is now if we have a vtable for for above classes.

And again the method of implementing virtual inheritance is implementation defined.

And honestly I don't know the answer to this.

Both gcc and clang have:

|           | 32 bit | 64 bit |
| --------- | ------ | ------ |
| sizeof(A) | 1      | 1      |
| sizeof(B) | 4      | 8      |
| sizeof(C) | 4      | 8      |
| sizeof(X) | 8      | 16     |

Which suggest that B and C each contain a pointer which are inherited by X. From what I can remember and reason about those are not pointers to vtables, but pointers (or offsets) that point to the interior of the structure, but I can't tell for sure.


(*) I take this opportunity again to mention that an entity declared with the struct keyword is a class.

bolov
  • 72,283
  • 15
  • 145
  • 224
  • Interesting stuff about the sizes, I expect the extra size to be due to the virtual inheritance - effectively creating a pointer to A, I checked with visual studio 2017. Same results for your example. Further investigation suggests that on that implementation the pointer is due to the virtual base, and adding a virtual function increases the size by an extra pointer (assume this is a v-table pointer). Moving to a Y shape from the diamond reduces size again. – ROX Nov 02 '17 at 18:24