Background
Apologies for "burying the lead." The questions are in the next section.
In my application, the purpose of inheritance is to abstract away complicated logic in the base class template, so that the writer of a derived class template doesn't need to worry about it. This logic, however, will depend on these simpler methods in the derived class.
What I have now is the base class template, something like base1
below, has the complicated function f2
, and this calls the to-be-defined, user-provided function f1
. I make f1
pure virtual so that gcc
spits out compiler errors if someone forgot to define it.
This works great, but I've starting considering what it would be like to rewrite base1
into something like base2
. From the user perspective, they don't need to worry about the weirdness of the base class inheriting stuff, so lack of familiarity with the curiously recurring template pattern wouldn't be an issue.
The downside to this would be a slightly higher burden being placed on the writer of the derived class template. The inheritance part changes from public base1<a>
to something that looks a little more intimidating: public base2<derived2<a>>
. So is there any speed gain that makes it worth it?
A baby example
#include <iostream>
// option 1
template<typename a>
class base1 {
public:
virtual double f1() = 0;
void f2() { std::cout << f1() << "\n"; }
};
template<typename a>
class derived1 : public base1<a> {
public:
virtual double f1() { return 1.0; }
};
// option 2
template<typename derived>
class base2 {
public:
void f2() { std::cout << static_cast<derived*>(this)->f1() << "\n"; }
};
template<typename a>
class derived2 : public base2<derived2<a>> {
public:
double f1() {return 1.0;}
};
int main() {
derived1<int> thing1;
thing1.f2();
derived2<int> thing2;
thing2.f2();
return 0;
}
Questions:
- Is it even polymorphism if there are no virtual functions, just pure virtual functions?
- Is there a vtable situation when there are just pure virtual functions? I've heard this is what makes static polymorphism faster (which might not even apply to this situation).
- What is different, from the compiler's perspective, about these two methods?