ssg
ssg

Reputation: 347

How many vtables gets created in below program?

I have seen few exmples showing vtables concepts in stackoverflow but given examples are only for single class, when we derived class from two abstract classes then how many vtables will be created for that class?

class A {
 public :
         virtual void func_1() = 0;
};

class B {
 public :
         virtual void func_2() = 0;
};

class C : public A, public B {
  public :
          void func_1()
          {
            cout << "func_1" << endl;
          }
          void func_2()
          {
            cout << "func_2" << endl;
};

In above example how many vtables will be there for class C, and will class A and class B have any vtables??

Upvotes: 3

Views: 150

Answers (2)

zwol
zwol

Reputation: 140748

In this specific case, C has one vtable and A and B have none. You can see this for yourself by out-of-lining C's member functions, so that the vtable will actually be emitted, and correcting the other compile errors:

extern "C" int puts(const char *);

struct A { virtual void func_1() = 0; };
struct B { virtual void func_2() = 0; };

struct C : A, B
{
  void func_1();
  void func_2();
};

void C::func_1() { puts("func_1"); }
void C::func_2() { puts("func_2"); }

... compiling to an object file, and then looking at the symbols:

$ gcc -c test.cc
$ nm test.o | c++filt
                 U puts
0000000000000000 T C::func_1()
000000000000001a T C::func_2()
0000000000000033 T non-virtual thunk to C::func_2()
0000000000000000 V typeinfo for A
0000000000000000 V typeinfo for B
0000000000000000 V typeinfo for C
0000000000000000 V typeinfo name for A
0000000000000000 V typeinfo name for B
0000000000000000 V typeinfo name for C
0000000000000000 V vtable for C
                 U vtable for __cxxabiv1::__class_type_info
                 U vtable for __cxxabiv1::__vmi_class_type_info

The compiler can prove that only the basic vtable for C is necessary because none of the classes have data or nontrivial constructors, and because A and B can't be instantiated directly. In the general case, there might be multiple vtables for all three classes. The exact rules for when multiple vtables are necessary are very complicated and I'm not going to try to summarize them here. They are spelled out in the "Itanium" C++ ABI, sections 2.5 and 2.6, but they probably won't make much sense if you're not accustomed to reading standardese and deeply familiar with the dark corners of C++; unfortunately I am not aware of any good overview of this for beginners. (It's been historically assumed that either you don't care or you are already an expert.) ("Itanium" is in quotes above because the spec was written with Itanium in mind, but the design was then adopted very widely. Unless you're using MSVC, you are probably getting this C++ ABI.) (To illustrate just how dark these dark corners are: I helped write this ABI spec, and yet I have no freaking idea why GCC thinks it needs to emit a "non-virtual thunk to C::func_2".)

Upvotes: 4

1stCLord
1stCLord

Reputation: 880

The only way to know for sure is to compile it and look, but in this case it's a virtual certainty that there will only be 1 vtable (maybe even 0 if you don't export the class). If either of the base classes weren't abstract the answer would be different depending on the compiler.

Upvotes: 1

Related Questions