oop — В C ++ приведение к подклассам для перегруженных функций?

Итак, вот ситуация:

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

Тогда лучи будут наложены лучом. Каждый луч будет проходить через этот массив моделей и проверять, сталкивается ли он с ними, используя свой собственный метод, Ray :: intersect. Таким образом, объявление Рэй включает в себя примерно следующее:

Point intersect(Sphere sphere) {...}

Point intersect(Cube cube) {...}

Point intersect(Torus torus) {...}

так далее

Проблема в том, что, поскольку все эти классы наследуются от Model, а массив относится к типовой модели, элементы будут иметь типовую модель при доступе к ним. Для модели нет пересечения, поэтому я не получу ошибку неправильного метода, так же как и ошибку такого метода. Итак, вопрос в том, как я могу привести каждого члена к соответствующему типу?

Есть ли разумный способ сделать это, или я должен попытаться привести каждый подкласс явно для каждого объекта и использовать любые палки? Это кажется очень хакерским для того, что кажется общей проблемой.

0

Решение

Вы должны сделать это наоборот. Вместо того, чтобы иметь Луч с Point intersect(Sphere sphere) и т. д. каждая модель должна иметь такую ​​функцию: virtual Point intersect(const Ray& ray) const,

PS. Кроме того, убедитесь, что ваш массив представляет собой массив Model * или некоторую форму интеллектуального указателя, в противном случае вы будете нарезать свои модели.

PPS. Настоящий трассировщик лучей нашел бы способ объединить свои лучи вместе, чтобы у вас не было так много (виртуальных) вызовов функций.

Редактировать:

Кроме того, возможно приведение к конкретной модели, но использование ее в этом случае разрушит OOP-сущность и приведет к появлению уродливого оператора switch. Например, предположим, у вас есть Model* modelи вы думаете, что это может быть Sphere*тогда вы можете сделать: Sphere* sphere = dynamic_cast<Sphere*>(model);, Если model был действительно Sphere*, затем sphere сейчас укажу на это, иначе sphere будет NULL, ИМО, вы должны стараться избегать использования dynamic_cast почти во всех ситуациях; если вы обнаружите, что должны его использовать, это, как правило, признак того, что ваш дизайн испортился (перепроектируйте или, если у вас нет времени, учитесь на своих ошибках).

1

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

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

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