Hi Genodians
I would like to create a hierarchy of classes on top of Fifo<>::Element so these object can be stored in fifos:
class A : public Fifo<A>::Element { virtual method() = 0; };
class B : public A { method() override { ... } };
This won't compile because Fifo<>::Element is missing a virtual destructor.
Is there any reason for this? What do you think about adding the virtual destructor to Fifo<>::Element?
Kind regards Stefan
Hi Stefan,
This won't compile because Fifo<>::Element is missing a virtual destructor.
Is there any reason for this? What do you think about adding the virtual destructor to Fifo<>::Element?
there are two reasons, efficiency and design:
* By adding a virtual destructor to 'Fifo<>::Element', each data type organized in a fifo would forcibly contain a vtable regardless of whether it contains virtual methods or not.
* The 'Element' type is merely needed as a place for the fifo's metadata. It is a technicality with no meaningful interface for anything except the 'Fifo' implementation. Hence, by publicly inheriting the "interface" of 'Fifo<>::Element', you'd pollute the interface of the derived class, adding complexity with no benefit.
The solution is the use private instead of public inheritance, thereby excluding 'Fifo<>::Element' from the interface of the derived class. Since the derived type cannot be casted to the 'Fifo<>::Element' type now, the virtual destructor is not needed. This makes the compiler happy.
The only remaining problem is that the 'Fifo<>' needs of course access to the 'Fifo<>::Element' interface. This can be granted by making the 'Fifo' a friend of the derived class.
For an example, take a look here:
https://github.com/genodelabs/genode/blob/master/repos/base/src/lib/ldso/inc...
Alternatively, you may consider the use of 'Fifo_element', which avoids inheritance altogether.
BTW, the same pattern is at work for 'Genode::List'. So you can find many more examples by grep'ing for "friend.*List".
Cheers Norman