Я использую двойную диспетчеризацию для получения расстояния между 2 объектами 2 классов (B
, C
), которые являются подклассами другого (A).
Я думаю, что методы в class A
должно быть чисто виртуальным, но они используются в другом тесте, поэтому class A
должен быть инстанцируемым, поэтому я не могу сделать их чисто виртуальными, верно?
Другое дело, что я не уверен, правильно ли я использую двойную диспетчеризацию, так как иногда генерирует бесконечный цикл в определении Distance(A *a)
в базовом классе.
в class A
У меня есть методы:
virtual double Distance(A *a) {return a->Distance(this);}
virtual double DistanceB(B *b) {return std::numeric_limits<double>::max();}
virtual double DistanceB(C *c) {return std::numeric_limits<double>::max();}
virtual double DistanceC(B *b) {return std::numeric_limits<double>::max();}
virtual double DistanceC(C *c) {return std::numeric_limits<double>::max();}
в class B
:
double B::Distance(A *a) { return a->DistanceB(this); }
double B::DistanceB(B *b) { /*calculate distance*/ }
double B::DistanceC(C *c) { return c->DistanceB(this); }
в class C
:
double C::Distance(A *a) { return a->DistanceC(this); }
double C::DistanceB(B *b) { /*calculate distance*/ }
double C::DistanceC(C *c) { /*calculate distance*/ }
virtual double Distance(A *a)
{return a->Distance(this);}
Так что если у меня есть:
A* a1, a2;
И я звоню:
a1->Distance(a2);
Вышеупомянутая реализация вызовет
a2->Distance(a1);
Который позвонит:
a1->Distance(a2);
…И это бесконечный цикл.
поскольку A
не является чисто абстрактным, вы должны также предоставить:
virtual double DistanceA(A *a);
virtual double DistanceA(B *b);
virtual double DistanceA(C *c);
virtual double DistanceB(A *a);
virtual double DistanceC(A *a);
И исправление
double A::Distance(A *a) {return a->DistanceA(this); }