[C++] how to pass a reference as a parameter

Started by
6 comments, last by PezMutanT 16 years ago
Hi people! Today is my first contact with references to types in C++ and I have a little question. My class hierarchy is like this: -Sprite ---Character ---Fire ---Wall ... As I would like to implement double dispatch, I have several methods in the parent class (Sprite):
[source language="C++"]
virtual void Sprite::CollisionWith(Character &refe);
virtual void Sprite::CollisionWith(Fire &refe);
virtual void Sprite::CollisionWith(Wall &refe);

But when it comes to call this functions I don't know how can I pass a reference as a parameter. The reference must be a reference of Sprite, just for the proper function is called in runtime. I have a vector with pointers to the Sprite class. I use an iterator too, so: iterator -> contents a pointer to a Sprite *iterator-> is a Sprite How can I manage to "cast" this iterator in order to the correct function is called? I'm sorry, I was looking up references in C++ but it's not clear to me. Thanks in advance! ;)
Advertisement
You pass the object as if you are passing it by value:

Something someThing;void foo( const Something& rSomething ){}foo ( someThing );

Any lvalue (google it!) can be implicitly converted to a reference. *iter is an lvalue. Therefore, *iter can be implicitly converted to a reference. (That assumes that iter is not a const iterator, of course.)
I think that the OP's problem is that he is iterating over Sprite pointers, but requires a reference to one of the derived classes to correctly call the collision handler.

Double dispatch means deciding which function to call based on the dynamic types of two objects, not just one like normal virtual functions. In C++, one can achieve that by having a virtual function in once derived class call a virtual function in another. Inside the implementation of a derived virtual function you know the type of the derived class (*this).

class Sprite{   virtual void CollisionWith(Character &);   virtual void CollisionWith(Fire &);   virtual void CollisionWith(Wall &);   virtual void CollisionWith(Sprite &) = 0;   static void handleCollision(Sprite &one, Sprite &two)   {       one.CollisionWith(two);       two.CollisionWith(one);   }};class Fire{    virtual void CollisionWith(Sprite &other)    {        // will call OtherType::CollisionWith(Fire &)        other.CollisionWith(*this);    }    // implement CollisionWith [ Character, Fire and Wall ] if required};class Wall{    virtual void CollisionWith(Sprite &other)    {        // will call OtherType::CollisionWith(Wall &)        other.CollisionWith(*this);    }    // implement CollisionWith [ Character, Fire and Wall ] if required};
I think I explained it poorly. If I pass **iterator to the function (that is the what is pointed by the iterator pointer, I think) then a Sprite object is passed as a parameter. That's almost what I want to do, as I want the right function to be called depending on the object class (it may be from the class Wall, it may be from the class Fire...).

Since I have different functions with the different kinds of parameters, I thought the right one would be called in runtime, but instead I'm getting this compile error:

error C2664: 'void Character::CollisionWith(Character &)' : cannot convert parameter 1 from 'Sprite' to 'Character &'

Also I don't know why the error specifies Character & and not Fire & or Wall &, because the three functions are inherited from Sprite class.

I hope I made it clearer now. Thank you all! ;)

PD: sorry rip-off, we posted at the same time
Ok, I *THINK* I finally understand.

So, in this example you wrote, if a Fire object collides with a Wall object, Fire::CollisionWith(Sprite &other) should be called with the Wall object as a parameter (but, of course as a Sprite object, not Wall), and then this method should call Wall::CollisionWith(Fire &other) , that's right?

So the key is the virtual function in the parent class with the parent class as a parameter, in this case:

virtual void CollisionWith(Sprite &) = 0;


I think I understand. Am I right now?

Thanks a lot rip-off!
Yes, I think you understand it. By calling a function fire.CollidesWith(wall), the wall's collision handler is called. This is the reason I added the static helper function to the sprite class, which calls both.
Ok, I was scared to ask for that static function, but now I fully understand your example. Thanks a lot rip-off! ;)

This topic is closed to new replies.

Advertisement