CRTP — derived class passes itself as template argument to base class.
1// CRTP mixin for counting objects2template<typename Derived>3class Counter {4 static int count;5public:6 Counter() { ++count; }7 Counter(const Counter&) { ++count; }8 ~Counter() { --count; }9 static int getCount() { return count; }10};1112template<typename Derived>13int Counter<Derived>::count = 0;1415class Dog : public Counter<Dog> {};16class Cat : public Counter<Cat> {};1718Dog d1, d2;19std::cout << Dog::getCount(); // 22021Cat c1;22std::cout << Cat::getCount(); // 12324// Static polymorphism (no virtual)25template<typename Derived>26class Shape {27public:28 void draw() {29 static_cast<Derived*>(this)->drawImpl();30 }31};3233class Circle : public Shape<Circle> {34public:35 void drawImpl() { std::cout << "Circle\n"; }36};
Advantages over virtual: