1

Suppose I have some class Base:

class Base {
public:
    auto foo() -> void { private_foo(); }
    auto bar() -> void;
private:
    auto private_foo() -> void;
};

There will never be and instance of Base; it acts only to define an interface and optionally some implementation (here implementation is in foo() and it calls a private function private_foo() which it is expecting to be defined by its derived classes). Derived will be a concrete type and will define the implementations of bar() and private_foo(). How can one best achieve this without using virtual inheritance?

My initial thoughts were to define Base as a class template:

template<typename T>
class Base {
public:
    auto foo() -> void { private_foo(); }
    virtual auto bar()=0 -> void;
private:
    virtual auto private_foo()=0 -> void;
};

Then Derived can be defined as such:

class Derived: public Base<Derived> {
public:
    auto bar() override -> void { // bar implementation };
private:
    auto private_foo() override -> void { // private_foo implementation};
};

Is this the best way? Am I correct in assuming that this does not create a virtual function pointer table? Is there a way that is cleaner or more idiomatic? I am aware that I am creating a template class using virtual inheritance, but my impression is that the 'virtual' aspect will be compiled away.

The goal is to create an interface without run-time overhead.

Tintin
  • 547
  • 5
  • 17
  • 4
    Maybe try to use a [CRTP](https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern), aka static polymorphism – πάντα ῥεῖ Aug 31 '19 at 07:35
  • "virtual inheritance" is not the same as inheriting from class with virtual functions. Virtual function pointer table will be created when there are some virtual functions. – user7860670 Aug 31 '19 at 07:35
  • Your `Base` class still introduces a vtable (and the overhead coming with it). With CRTP you just use `static_cast`s from the `Derived` `this` pointer. – πάντα ῥεῖ Aug 31 '19 at 07:38
  • @πάνταῥεῖ This is actually what I tried to achieve - modifying OPs sample. However, it fails due to `private: private_foo()`. Something is missing. [**Attempt on coliru**](http://coliru.stacked-crooked.com/a/911f65212e75566a). Any idea? (I didn't want `friend class Base;` in `Derived` but I don't know how to come around.) – Scheff's Cat Aug 31 '19 at 07:41
  • With `friend class Base;` in `Derived` it would work: [**Demo on coliru**](http://coliru.stacked-crooked.com/a/cc46b032f414ca9d). :-( – Scheff's Cat Aug 31 '19 at 07:43
  • @Scheff The major flaw in the OP's question is, that they still introduce a `virtual` function in their example (and thus not get rid of the overhead). – πάντα ῥεῖ Aug 31 '19 at 07:52
  • @πάνταῥεῖ This is something I realized and agree on. Hence, I tried to make a sample without `virtual` but keeping `private_foo()` `private` in `Derived` (what I considered as intention of the whole fiddling). However, I gave up with my 2nd attempt ;-) (...but I might've overseen something clever). – Scheff's Cat Aug 31 '19 at 07:55
  • @πάνταῥεῖ CRTP seems like the correct solution. I presume that `private_foo()` cannot appear in the definition of `Base` and so it needs to be documented that `Derived` must implement it (it cannot be documented by the code). – Tintin Aug 31 '19 at 08:09
  • @Tintin It will be _"documented"_ since you get compiler errors otherwise. – πάντα ῥεῖ Aug 31 '19 at 08:11

0 Answers0