Question about pure virtual functions (abstract classes)

Hey,

Im still trying to figure out when I should use pure virtual functions.

On the one hand, "TOY" for example should be an abstract class since theres no such thing as "TOY" , there are "toy cars", "toy fighters" etc , but on the other hand I need to force it somehow to be abstract since theres no really a function that any toy should have and implement on his own way (except PRINT maybe).

So.. what do you guys suggest? when I should REALLY use pure virtual functions?
And if I want to avoid people from creating TOY objects (for example), the only way is PURE virtual functions. right?

thank you very much..

Roy.
Last edited on
You should REALLY use pure virtual functions when dealing with interface classes.
On the one hand, "TOY" for example should be an abstract class since theres no such thing as "TOY" , there are "toy cars", "toy fighters" etc , but on the other hand I need to force it somehow to be abstract since theres no really a function that any toy should have and implement on his own way (except PRINT maybe).


There are other ways to enforce the non creation of objects of the TOY class - make all the constructors protected. As MiiNiPaa said, you use pure virtual functions to make an interface - which is a really good and powerful idea. Pure virtual functions must be redefined in derived classes, but ordinary virtual functions may be redefined if you wish. Sometimes this is handy because you can define your function once high up in the inheritance tree.

If the TOY class has no functions that need to be inherited by the derived classes, then you have a design problem. You should try to push you functions as high up the inheritance tree as possible. Make use of polymorphism so that you can make the functions as general as possible in terms of their parameters. By this I mean that you make use of the fact that a pointer to a derived class is a valid pointer to a base class. The function parameter is a pointer to the base class, but the argument you send to the function is a pointer to a derived class. This is also a very powerful idea.

HTH
Thank you very much for the answer TheIdeasMan.

If I had a function named "PLAY" inside the toy class, would it be wise to make it a pure virtual function since every toy is played differently?

Yes, and this is the start of your interface to your Toy classes. As I hinted at earlier, I would have one of the parameters being a pointer to the Toy Base class. See below for a different way of doing things with the CActor class.

The idea of the interface is to have a whole inheritance tree with a set of general functions that have consistent calling parameters to deal with all of the classes.

As to whether a function should be pure virtual or not, depends on what is being done. You should use pure virtual functions for the interface, but then you might have a branch of the inheritance tree that has a behaviour that is specific to that branch. So you could have an ordinary virtual function if there is still more specialisation, or just an ordinary function if their behaviour is the same.

For example, say you have a Room which consists of a 2d array of Tiles. You could have an ordinary virtual function called Move in the Toy class which is defined once and inherited through the whole tree, because it is the same no matter what object is being moved.

1
2
3
4
virtual void CToy::Move(CToy *TheToy, CTile * TheTile) {   // C means class 

//Your code here
}


I would think about what you mean exactly by the Play function - always think about about what the object is capable of doing. Instead of just the Play function, you could have various functions such as Move, Acquire (some resource such as gold or a weapon that lying around), Attack, Place (something a bomb say). Each of these functions could be put in the base class (CActor shown below) and be virtual - not necessarily pure - you may want to leave the behaviour to be inherited.

I would also consider having classes declarations like this:

1
2
3
4
5
6
7
8
class CActor ; //put common function in here
class CPlayer : public CActor ; // Players are on our side
class CEnemy : public CActor ;

class CWeapon {};
class CSword : public CWeapon ;
class CGun : public CWeapon;


These classes can be extended to cover all sorts of different things.

There is an even more complex way of doing these things which involves using the Mediator Design pattern (Google that if interested)- I am working on this at the moment.

I hope this has given you a bit to think about - and plenty to go on with. Have fun :D !!!!

Topic archived. No new replies allowed.