aka John M. Never give up. Never surrender!
Pure virtual functions and parameters in ...
My questions deals with a base class(abstract) which other objects will inherit from. First a quick code example:
class BaseObj {
public:
virtual int DrawObject() = 0; //make it defined elsewhere
}
class inherited : public BaseObj {
public:
virtual int DrawObject() {}; // function defined here
}
class inherited2 : public BaseObj {
public:
virtual int DrawObject(LPDIRECTDRAWSURFACE);
}
Q#1) Since these inherited class MUST "define" the function DrawObject() ..what if as in class inherited i dont use it will a "definition" of just the curly braces be alright {} as above?
Q#2) If you notice in class inherited2, the virtual function is "defined" from its base class with something extra, a PARAMETER!
IS THIS allowed? Can the inherited classes ADD parameters to this virtual function and it will still be called ok?
Q#2.a) If adding parameters to newer definition of a virtual function wont work, is there a way to make it so FUTURE definitions can have different parameters but same inherited function call...like some kind of void parameter??
Im designing my objects for a tilebased game and before i go further i kind of need to know about these before i go diving in
December 30, 2000 08:44 PM
Q1) Defining an empty function (just using curly braces with nothing between them) is fine. If that function is called, it won''t execute anything.
Q2) As far as I know, you cannot add variables to functions and still have it work.
Q3) You could either declare both versions of the function in the abstract base class (ie 1 with no paramters and 1 with a single parameter). It will simply overload it so it could be called either way. Alternatively, you could declare the version in the base class to take a single parameter, but give a default value to that parameter. For example, in the base class you could have
virtual int f(Object *O = NULL) = 0;
I''ve never used that in an abstract case, but it should work. What it does is that if you call f(), the function is executed as if O was a NULL pointer, or it could be called f(SomeObject) where SomeObject is a pointer to an Object.
Hope that helps
Q2) As far as I know, you cannot add variables to functions and still have it work.
Q3) You could either declare both versions of the function in the abstract base class (ie 1 with no paramters and 1 with a single parameter). It will simply overload it so it could be called either way. Alternatively, you could declare the version in the base class to take a single parameter, but give a default value to that parameter. For example, in the base class you could have
virtual int f(Object *O = NULL) = 0;
I''ve never used that in an abstract case, but it should work. What it does is that if you call f(), the function is executed as if O was a NULL pointer, or it could be called f(SomeObject) where SomeObject is a pointer to an Object.
Hope that helps
December 30, 2000 08:55 PM
Q#1 - Compliation wise, yes. Implementation wise, depends on your design
Q#2 - Look up function overloading and function delclaration in your help files. You now have two completely different functions now as the signatures differ from each other. Again, whether this works depends on your design implementation
Q#2.a - See Q#2 or consider the following:
class inherited2 : public BaseObj {
public:
inherited2(LPDIRECTDRAWSURFACE) {/*...*/}
//or
int AttachSurface(LPDIRECTDRAWSURFACE);
// and
int DrawObject() { /*...*/ }
// instead of
//virtual int DrawObject(LPDIRECTDRAWSURFACE);
private:
LPDIRECTDRAWSURFACE _lpdd;
};
Although completely legal to change your contract with the BaseObj interface via inherited2, doing the above extends derived classes while still maintaining consistency with your BaseObj interface (say like a BaseObj* pointing to an instance of inherited2).
Don''t know if this makes any sense. Of course someone will probably come along and tell me I''m wrong. Your overall curiosity falls under a *morality* concept rather than a *legality* one. Therefore, some of this will be opinion based and can differ.
Q#2 - Look up function overloading and function delclaration in your help files. You now have two completely different functions now as the signatures differ from each other. Again, whether this works depends on your design implementation
Q#2.a - See Q#2 or consider the following:
class inherited2 : public BaseObj {
public:
inherited2(LPDIRECTDRAWSURFACE) {/*...*/}
//or
int AttachSurface(LPDIRECTDRAWSURFACE);
// and
int DrawObject() { /*...*/ }
// instead of
//virtual int DrawObject(LPDIRECTDRAWSURFACE);
private:
LPDIRECTDRAWSURFACE _lpdd;
};
Although completely legal to change your contract with the BaseObj interface via inherited2, doing the above extends derived classes while still maintaining consistency with your BaseObj interface (say like a BaseObj* pointing to an instance of inherited2).
Don''t know if this makes any sense. Of course someone will probably come along and tell me I''m wrong. Your overall curiosity falls under a *morality* concept rather than a *legality* one. Therefore, some of this will be opinion based and can differ.
re: Q2 & Q2.a:
The whole reason for having a pure virtual function in the base class is so that some function can come along and call that function on all objects derived from the base class without caring what the exact derivations are.
Example, the whole reason to have a BaseObj class with a DrawObject member function is so that your main game loop can iterate through a container of all visible objects and call "DrawObject" on each, not caring what type of each object is as long as it''s derived from BaseObj.
Two functions with the same name but different parameters are different functions. They are not the same. If they are both virtual, they will each take up one slot in the virtual function pointer table.
When you add overloads for derived classes, this means that you will not be able to call these new functions with a base class pointer unless you also declare the new overloads for the base class. This also means that every derived class will have to implement every overload of the function.
To make a long story short, this is probably not what you want to be doing. You seem to be defeating the purpose of polymorphism if you require separate overloads for each type of derived class. You should either rethink some way that all of your derived classes can use a single DrawObject function without overloading it, or split the classes into separate base classes and always keep them apart.
The whole reason for having a pure virtual function in the base class is so that some function can come along and call that function on all objects derived from the base class without caring what the exact derivations are.
Example, the whole reason to have a BaseObj class with a DrawObject member function is so that your main game loop can iterate through a container of all visible objects and call "DrawObject" on each, not caring what type of each object is as long as it''s derived from BaseObj.
Two functions with the same name but different parameters are different functions. They are not the same. If they are both virtual, they will each take up one slot in the virtual function pointer table.
When you add overloads for derived classes, this means that you will not be able to call these new functions with a base class pointer unless you also declare the new overloads for the base class. This also means that every derived class will have to implement every overload of the function.
To make a long story short, this is probably not what you want to be doing. You seem to be defeating the purpose of polymorphism if you require separate overloads for each type of derived class. You should either rethink some way that all of your derived classes can use a single DrawObject function without overloading it, or split the classes into separate base classes and always keep them apart.
GalaxyQuest - I think Stoffel presents my point better than I did. So for the most part, you can do what your original questions were asking, however if you read Stoffel''s post and understand what he''s saying I think you''ll find your approach circumvents what your trying to accomplish. (Again, what Stoffel points out)
YAP-YFIO,
deadlinegrunt
YAP-YFIO,
deadlinegrunt
~deadlinegrunt
You have all made good points about my question.
I beleive STOFFEL was the closest in what i am attempting to do, which is within my tilebased map, each tile includes a SINGLE LINKED LIST of all OBJECTS on that tile. For this its best to be able to call the draw() function for each item in the list no matter what it is.(at least thats my thoughts about what i want to do)
And that is the hardest part for me right now. I have to think about way in the future about how these objects will be used and whether or not i can declare them all from a single base type or not or do i CHANGE THE LINKED LIST...very difficult for me at this point to really know what is "best". I have right right now the following lineage(family tree)
*I am in this beginning design/implement stage, so its still up in the air as for whether it stays this way*
CObject (base class)
CFixedObj : public CObject (inherits base)
CMovingObj: public CFixedObj (inherits from Cfixed, .. and down)
Here is how my design is breaking them up:
-My fixed objects are things like items(weapons, cups, food), trees, rocks, statues, buildings.
-My moving objects should include: AMMO, player, NPC''s(enemy and townfolk), animals.
Fixed class and moving class both use same sprite class(declared in the fixed class), which is why i inherited my Moving class from fixed. yuck that sounds confusing but hope u understood that.
Biggest difference will be the ai structures i need to create in the Moving class to control them (not designed yet).
So, as you can see, i have broken down my objects but still there are a lot of gray areas i havnt hit yet and probably wont until that code is needed.
Anyways, this is where i am and stoffel (as well as all the rest of you kind folks) were pretty right on what i want to do.
Do my classes seem to be broken up in a good fashion or not?
I beleive STOFFEL was the closest in what i am attempting to do, which is within my tilebased map, each tile includes a SINGLE LINKED LIST of all OBJECTS on that tile. For this its best to be able to call the draw() function for each item in the list no matter what it is.(at least thats my thoughts about what i want to do)
And that is the hardest part for me right now. I have to think about way in the future about how these objects will be used and whether or not i can declare them all from a single base type or not or do i CHANGE THE LINKED LIST...very difficult for me at this point to really know what is "best". I have right right now the following lineage(family tree)
*I am in this beginning design/implement stage, so its still up in the air as for whether it stays this way*
CObject (base class)
CFixedObj : public CObject (inherits base)
CMovingObj: public CFixedObj (inherits from Cfixed, .. and down)
Here is how my design is breaking them up:
-My fixed objects are things like items(weapons, cups, food), trees, rocks, statues, buildings.
-My moving objects should include: AMMO, player, NPC''s(enemy and townfolk), animals.
Fixed class and moving class both use same sprite class(declared in the fixed class), which is why i inherited my Moving class from fixed. yuck that sounds confusing but hope u understood that.
Biggest difference will be the ai structures i need to create in the Moving class to control them (not designed yet).
So, as you can see, i have broken down my objects but still there are a lot of gray areas i havnt hit yet and probably wont until that code is needed.
Anyways, this is where i am and stoffel (as well as all the rest of you kind folks) were pretty right on what i want to do.
Do my classes seem to be broken up in a good fashion or not?
aka John M.
Never give up. Never surrender!
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement
Recommended Tutorials
Advertisement