Bez funkcji wirtualnych zrobisz to łatwo z użyciem CRTP (ang. Curiously recurring template pattern) chodzi o ten idiom językowy:
class Y : public X<Y> {
//...
};
Np. tak:
#include <iostream>
template<typename T>
struct Base {
static int familyData;
int getFamilyData() const {
return Base::familyData;
}
int getChildData() const {
return T::childData;
}
};
template<typename T>
int Base<T>::familyData = 42;
struct Derived: Base<Derived> {
static int childData;
};
int Derived::childData = 242;
int main() {
Derived derived;
std::cout << derived.getFamilyData() << std::endl;
std::cout << derived.getChildData() << std::endl;
}
Oczywiście można i virtualem :-)