简体   繁体   中英

In C++, casting to subclasses for overloaded functions?

So here's the situation:

I have an abstract superclass "model" for a raytracer program, from which various kind of geometry inherit properties and functions. There will be no objects of type model, obviously, but there will be an array of type model in which the entire geometry of the scene will be stored.

Then a number of Rays will be cast by the raytracer. Each ray will iterate through this array of models and check if it collides with them using its own method, Ray::intersect. Thus, Ray's declaration includes approximately this:

Point intersect(Sphere sphere) {...}

Point intersect(Cube cube) {...}

Point intersect(Torus torus) {...}

etc

Problem is, since all of these classes inherit from Model, and the array is of type model, the elements will be of type model when they are accessed. There is no intersect for model, so I won't get a wrong-method error so much as a no-such-method error. So the issue is: how can I cast each member to its appropriate type?

Is there a reasonable way to do this, or must I try casting each subclass explicitly for each object, and using whatever sticks? This seems very hackish for what seems like a common problem.

You should do it the other way around. Instead of having the Ray with Point intersect(Sphere sphere) etc., each Model should have a function like: virtual Point intersect(const Ray& ray) const .

PS. as an aside, make sure your array is array of Model* or some form of smart pointer, otherwise you will be slicing your Models.

PPS. A real ray tracer would find a way to batch up their rays together, so you don't have so many (virtual) function calls.

Edit:

Also, it is possible to cast to a particular model, but using it in this case will ruin the OOP-ness, and result in an ugly switch statement. For example, suppose you have a Model* model , and you think it might be a Sphere* , then you can do: Sphere* sphere = dynamic_cast<Sphere*>(model); . If model was indeed a Sphere* , then sphere will now point to it, otherwise sphere will be NULL . IMO you should try to avoid using dynamic_cast in almost all situations; if you find that you must use it, it is usually a sign that your design messed up (redesign, or if you haven't time, learn from your mistakes).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM