C ++ Overload Resolution

I want to use inheritance so that the object is handled differently, depending on where in the hierarchy it falls

( similar to this C # question )

Suppose you create a hierarchy of Shape objects, for example:

class Shape {} ; class Sphere : public Shape {} ; class Triangle : public Shape {} ; ... 

Then you equip the Ray class with methods such as:

 class Ray { Intersection intersects( const Sphere * s ) ; Intersection intersects( const Triangle * t ) ; }; 

You store an array of various shapes * of various types and call

 vector<Shape*> shapes ; ... //foreach shape.. Intersection int = ray.intersects( shapes[ i ] ) 

But you get a compiler error

error C2664: 'Intersection Ray :: intersects (const Sphere *) const': cannot convert parameter 1 from 'Shape * const' to 'const Sphere *'

How are you wrong?

This is the only way to do it the other way,

 class Shape { virtual Intersection intersects( const Ray* ray )=0 ; } ; 

then does each class override the intersection? Then calls

 //foreach shape.. Intersection int = shapes[i]->intersects( ray ) ; 

Can you do this in the first way that I showed or NEVER?

+7
source share
3 answers

You should do it the other way around. Overload resolution occurs during compilation, when the type of what you call it with is Shape* .

+4
source

No, you cannot do this in the first way. Overload resolution in C ++ is based on static types of function arguments. It is resolved at compile time. In your example, the static type is Shape * , and in your class there is no function that would accept Shape * (hence the error). The compiler does not care that your pointer can point to Sphere at run time.

To implement what you are trying to implement, you must “route” your calls through an object that uses dynamic types of objects, that is, through calls to virtual functions, which you do in your second example.

The second example is a little simplified, since the type of one of the involved objects is known at compile time ( Ray ). In a more complex case, both objects involved in the “intersection” can be dynamically printed. If you want to process something like this, you can use the so-called “double-send” technique (look for it).

+4
source

Maybe you can pull this with the RTTI information. I did not do this, but it is possible.

 class Ray { Intersection intersects( const Sphere * s ) ; Intersection intersects( const Triangle * t ) ; Intersection intersects( const Shape * s ) { //act on RTTI info, or //use dynamic_cast to other types and check if the result is NULL or not } }; 
0
source

All Articles