Suppose I have these abstract classes Foo
and Bar
:
class Foo;
class Bar;
class Foo
{
public:
virtual Bar* bar() = 0;
};
class Bar
{
Doesn't static polymorphism solve your problem? Feeding the base class with the derived class through template argument? So the base class will know the derivative Type and declare a proper virtual?
How about this.
template <class BarType>
class Foo
{
public:
virtual BarType* bar() = 0;
};
template <class FooType>
class Bar
{
public:
virtual FooType* foo() = 0;
};
class ConcreteBar;
class ConcreteFoo : public Foo<ConcreteBar>
{
public:
ConcreteBar* bar();
};
class ConcreteBar : public Bar<ConcreteFoo>
{
public:
ConcreteFoo* foo();
};
You can fake it quite easily, but you lose the static type checking. If you replace the dynamic_casts
by static_casts
, you have what the compiler is using internally, but you have no dynamic nor static type check:
class Foo;
class Bar;
class Foo
{
public:
Bar* bar();
protected:
virtual Bar* doBar();
};
class Bar;
{
public:
Foo* foo();
public:
virtual Foo* doFoo();
};
inline Bar* Foo::bar() { return doBar(); }
inline Foo* Bar::foo() { return doFoo(); }
class ConcreteFoo;
class ConcreteBar;
class ConcreteFoo : public Foo
{
public:
ConcreteBar* bar();
protected:
Bar* doBar();
};
class ConcreteBar : public Bar
{
public:
ConcreteFoo* foo();
public:
Foo* doFoo();
};
inline ConcreteBar* ConcreteFoo::bar() { return &dynamic_cast<ConcreteBar&>(*doBar()); }
inline ConcreteFoo* ConcreteBar::foo() { return &dynamic_cast<ConcreteFoo&>(*doFoo()); }
Covariance is based on inheritance diagram, so since you cannot declare
class ConcreteBar : public Bar;
hence no way to tell compiler about covariance.
But you can do it with help of templates, declare ConcretFoo::bar as template and later bounding allows you solve this problem