#include <iostream>
#include <memory>
class D1;
class D2;
class D3;
class Base {
public:
void func(const D1& obj) const
{
return this->applyFunc(obj);
}
void func(const D2& obj) const
{
return this->applyFunc(obj);
}
void func(const D3& obj) const
{
return this->applyFunc(obj);
}
private:
virtual void applyFunc(const D1& obj) const = 0;
virtual void applyFunc(const D2& obj) const = 0;
virtual void applyFunc(const D3& obj) const = 0;
};
class D1 : public Base {
private:
// Inherited via Base
virtual void applyFunc(const D1& obj) const override
{
std::cout << "D1 & D2" << std::endl;
return;
}
virtual void applyFunc(const D2& obj) const override
{
std::cout << "D2 & D2" << std::endl;
return;
}
virtual void applyFunc(const D3& obj) const override
{
std::cout << "D3 & D2" << std::endl;
return;
}
};
class D2 : public Base {
private:
// Inherited via Base
virtual void applyFunc(const D1& obj) const override
{
std::cout << "D2 call D1" << std::endl;
return;
}
virtual void applyFunc(const D2& obj) const override
{
std::cout << "D2 call D2" << std::endl;
return;
}
virtual void applyFunc(const D3& obj) const override
{
std::cout << "D2 call D3" << std::endl;
return;
}
};
class D3 : public Base {
private:
void printDontCallMe() const
{
std::cout << "Don't call me." << std::endl;
return;
}
private:
// Inherited via Base
virtual void applyFunc(const D1& obj) const override
{
this->printDontCallMe();
return;
}
virtual void applyFunc(const D2& obj) const override
{
this->printDontCallMe();
return;
}
virtual void applyFunc(const D3& obj) const override
{
this->printDontCallMe();
return;
}
};
int main()
{
const auto d1 = std::make_unique<const D1>();
const auto d2 = std::make_unique<const D2>();
const auto d3 = std::make_unique<const D3>();
d1->func(*d1); d1->func(*d2); d1->func(*d3);
d2->func(*d1); d2->func(*d2); d2->func(*d3);
d3->func(*d1); d3->func(*d2); d3->func(*d3);
return 0;
}