Рекомендации по структуре классов в системе обнаружения столкновений

C ++ — это первый язык, который я широко использовал, который использует объектную ориентацию, поэтому я все еще немного новичок в этой идее. Я пытаюсь перенести библиотеку игр, над которой я работал, с Go (который использует интерфейсы вместо настоящей ООП-системы) на C ++.

У меня есть система столкновений, которая использует четыре типа: точку, границу, линию и многоугольник. То, что я хотел бы сделать, это сделать все это абстрагируемым в класс «Collider» и иметь функцию, которая может принимать два объекта Collider и проверять их на столкновение. Это будет выглядеть примерно так:

bool Collides(Collider obj1, Collider obj2);

Первоначально я думал, что у меня могут быть методы для каждого типа коллизии, которые будут проверять коллизию, заданную другим типом (т. Е. Методы OnPoint, OnBounding, OnLine и OnPolygon), а затем иметь «Collider» как виртуальный класс, который требует все эти методы, но затем я понял, что это было бы невозможно в C ++, потому что классы зависели бы друг от друга для компиляции (верно?).

Я немного растерялся из-за того, что еще я могу сделать. Является ли моя дизайнерская идея несбыточной мечтой?

0

Решение

Вам нужна функция, которая отправляет не только первый аргумент, но и второй, т. Е. Двойную диспетчеризацию. Это не поддерживается напрямую в C ++, но может быть эмулировано.

class Collider {
public:
virtual bool Collides(Collider const& x) const = 0;

private:
virtual bool Collides(Point const& p) const = 0;
virtual bool Collides(Line const& l) const = 0;
};

class Point: public Collider {
public:
virtual bool Collides(Collider const& x) const {
// here, the type of this is now Point
// now, find out what x is and call the overload on this type
x.Collides(*this);
}

private:
virtual bool Collides(Point const& p) const {
// we now know that we are a point and checking vs. another point
}

virtual bool Collides(Line const& l) const {
// we now know that we are a point and checking vs. a line
}
};

class Line: public Collider {
public:
virtual bool Collides(Collider const& x) const {
// here, the type of this is now Line
x.Collides(*this);
}

private:
virtual bool Collides(Point const& p) const {
// we now know that we are a line and checking vs. a point
}

virtual bool Collides(Line const& l) const {
// we now know that we are a line and checking vs. another line
}
};

Теперь проверка двух объектов выполнит две отправки во время выполнения:

Collider* p = new Point();
Collider* l = new Line();

p.Collides(l)
// first dynamically dispatches on p to call Point::Collides
// in Collides, this (which is p) now has the static Point.
// now do the second dispatch on l and use *this as the parametet
// to find the overload.

Это, например, используется в Шаблон дизайна посетителя. Если ваш набор объектов фиксирован, но вы ожидаете, что операции над ними будут изменены или расширены, Visitor — хороший выбор.

1

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]