#include <iostream>
#include <memory>
#include <array>
class PureCrtpInterface
{
public:
virtual ~PureCrtpInterface()
{ }
virtual void kung() = 0;
virtual void foo() = 0;
};
template <typename T>
class CrtpBase : public PureCrtpInterface
{
public:
virtual ~CrtpBase()
{ }
void kung() override
{
static_cast<T*>(this)->kung_impl();
}
void foo() override
{
static_cast<T*>(this)->foo_impl();
}
protected:
virtual void kung_impl() = 0;
virtual void foo_impl() = 0;
};
class Derived1 : public CrtpBase<Derived1>
{
public:
virtual ~Derived1()
{ }
void kung_impl() override
{
std::cout << "Derived1::kung_impl()" << std::endl;
}
void foo_impl() override
{
std::cout << "Derived1::foo_impl()" << std::endl;
}
};
class Derived2 : public CrtpBase<Derived2>
{
public:
virtual ~Derived2()
{ }
void kung_impl() override
{
std::cout << "Derived2::kung_impl()" << std::endl;
}
void foo_impl() override
{
std::cout << "Derived2::foo_impl()" << std::endl;
}
};
class Derived3 : public Derived2
{
public:
virtual ~Derived3()
{ }
void kung_impl() override
{
std::cout << "Derived3::kung_impl()" << std::endl;
}
void foo_impl() override
{
std::cout << "Derived3::foo_impl()" << std::endl;
}
};
int main() {
std::array<std::shared_ptr<PureCrtpInterface>, 3> arr= {
std::make_shared<Derived1>(),
std::make_shared<Derived2>(),
std::make_shared<Derived3>()
};
arr[1]->kung();
arr[2]->foo();
return 0;
}