Итак, вот ситуация:
У меня есть абстрактная «модель» суперкласса для программы raytracer, от которой различные виды геометрии наследуют свойства и функции. Очевидно, что не будет объектов модели типов, но будет массив моделей типов, в котором будет храниться вся геометрия сцены.
Тогда лучи будут наложены лучом. Каждый луч будет проходить через этот массив моделей и проверять, сталкивается ли он с ними, используя свой собственный метод, Ray :: intersect. Таким образом, объявление Рэй включает в себя примерно следующее:
Point intersect(Sphere sphere) {...}
Point intersect(Cube cube) {...}
Point intersect(Torus torus) {...}
так далее
Проблема в том, что, поскольку все эти классы наследуются от Model, а массив относится к типовой модели, элементы будут иметь типовую модель при доступе к ним. Для модели нет пересечения, поэтому я не получу ошибку неправильного метода, так же как и ошибку такого метода. Итак, вопрос в том, как я могу привести каждого члена к соответствующему типу?
Есть ли разумный способ сделать это, или я должен попытаться привести каждый подкласс явно для каждого объекта и использовать любые палки? Это кажется очень хакерским для того, что кажется общей проблемой.
Вы должны сделать это наоборот. Вместо того, чтобы иметь Луч с 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
почти во всех ситуациях; если вы обнаружите, что должны его использовать, это, как правило, признак того, что ваш дизайн испортился (перепроектируйте или, если у вас нет времени, учитесь на своих ошибках).
Других решений пока нет …