Virtual base classes

At times, it doesn't make a lot of sense for a base class to have an implementation for a class method, yet at the same time we wish to force any derived classes to implement that method. The answer to this problem is virtual methods.

Take the following class definition:

class A { 
public: 
   virtual bool methodA() = 0; 
   virtual bool methodB() = 0; 
}; 

If we try to derive from this class, we must implement these two class methods or get a compiler error. Since both of the methods in the base class are virtual, the entire base class is referred to as a virtual base class. This is particularly useful for when you wish to define an interface that can be implemented by a range of different classes, yet keep the convenience of having just one user-defined type to refer to.

Internally, virtual methods like these are implemented using vtables, which is short for virtual table. This is a data structure containing, for each virtual method, a memory address (pointer) pointing to an implementation of that method:

VirtualClass* → vtable_ptr → vtable[0] → methodA() 

We can compare the performance impact of this level of indirection relative to C-style code and classes with direct method calls. The Code Craft article on the timing of virtual functions (https://hackaday.com/2015/11/13/code-craft-embedding-c-timing-virtual-functions/) describes such an approach, with interesting findings:

Uno

Due

 

 

Os

O2

Os

O2

 

C function call

10.4

10.2

3.7

3.6

C++ direct call

10.4

10.3

3.8

3.8

C++ virtual call

11.1

10.9

3.9

3.8

Multiple C calls

110.4

106.3

39.4

35.5

C function pointer calls

105.7

102.9

38.6

34.9

C++ virtual calls

103.2

100.4

39.5

35.2

All times listed here are in microseconds.

The same two Arduino development boards are used for this test as for the one comparing compile output size between C code and C++ classes. Two different optimization levels are used to compare the impact of such compiler settings: -Os optimizes for the size of the resulting binary in terms of bytes, where as the -O2 setting optimizes for speed in a more aggressive manner than the -O1 optimization level.

From these timings, we can say for sure that the level of indirection introduced by the virtual methods is measurable, although not dramatic, adding a whole 0.7 microseconds on the ATMega328 of the Arduino Uno development board, and about 0.1 microseconds on the faster ARM-based board.

Even in absolute terms, the use of virtual class methods does not carry enough of a performance penalty to truly reconsider its use unless performance is paramount, and this is primarily the case on slower MCUs. The faster the MCU's CPU, the less severe the impact of its use will be.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.119.131.72