Мне трудно найти (что я уверен, что это очень распространенный) шаблон проектирования, чтобы обойти следующую проблему.Рассмотрим этот фрагмент кода:
class AA {};
class BB : public AA {};
class A
{
public:
virtual void foo(AA& aa) = 0;
};
class B : A
{
public:
void foo(BB& bb){cout<<"B::foo"<<endl;}
};
int main()
{
B b;
BB bb;
b.foo(bb);
}
Этот код не будет компилироваться, поскольку класс B не переопределяет чисто виртуальную функцию 'foo'.Компилятор рассматривает foo, который B объявляет только как перегрузку для foo, потому что ковариация не допускается во входных параметрах в переопределенных функциях.
Теперь я понимаю причину этого.Тот факт, что B наследуется от A, означает, что он должен иметь возможность обрабатывать любые вызовы foo с параметрами типа AA, а предыдущий код не дал никакой реализации для обработки любого типа параметра, кроме BB.
Конечно, я могпросто приведите aa к BB в реализации boo foo, но я ищу решение, которое сохраняет безопасность типов и фактически заставляет разработчика класса B также реализовать класс, который наследуется от AA, чтобы код компилировался.В идеальном мире я мог бы написать что-то похожее на этот псевдокод:
class A
{
public:
abstract class AA{}; //indicates that any child of A must implement also child of AA
abstract void foo(AA& aa);
};
class B : public A
{
public:
class BB : AA{}; //will not compile without this
void foo(BB& bb){cout<<"B::foo"<<endl;}
};
Есть ли способ достичь чего-то похожего в C ++?(возможно, это может быть сделано с помощью какого-либо объекта сопоставления без необходимости наследования)
Обратите внимание, что в действительности (в отличие от примера) наследование между BB и AA имеет решающее значение, так как у AA много детей, которые обладают многими качествамии, в конце концов, я хочу выполнить итерацию по вектору классов A и запустить 'foo' только с соответствующими параметрами (вектором AA)