CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 1 of 2 12 LastLast
Results 1 to 15 of 21
  1. #1
    Join Date
    Jan 2010
    Posts
    3

    Question Polymorphism; How to get the specific class?

    Alrighty, so.

    I have an (abstract) class named BaseObject, whose purpose is just to be extended upon. Next, I have a VisualObject class, which inherits from the BaseObject class. Next, I have a Player class, which inherits from the VisualObject class and the BaseObject class (through the VisualObject class).

    The thing is, I am currently looping through a list of BaseObjects (which get added to the list when I create an instance of the Player or VisualObject class) and trying to find out if the object I have looped into is a Player class. That part is simple; I have been able to identify which BaseObject in the list corresponds to a Player object.

    The part I'm having trouble with is that I have another class, TileMaster, who wants to change the coordinates of the instance of the player identified through the previous loop, but the BaseObject class doesn't have x or y variables, but the Player (and VisualObject) do.

    The way that I have the engine set up, I am unable to just reference the Player object itself; It is being created by another object in a different part of the program.

    Here is some code to help identify what I am trying to do:

    Code:
    BOOST_FOREACH (BaseObject* object, baseObjects) //loop through the list
    {
    	// if the variable set in the BaseObject is a Player set number
    	if(object->objectType == 2)
    		 // allow the tile master to change properties of the Player by ONLY knowing the BaseObject. Problems here
    		tilemaster->SetPlayerPos(object, THE_X_I_CHOOSE, THE_Y_I_CHOOSE);
    }
    Player.cpp:
    Code:
    Player::Player(int numPlayer) :
    	VisualObject("media/player.png"),
    	thisPlayerNum(numPlayer),
    	isMoving(false),
    	isJumping(false),
    	objectType(2) // identifies that the object type looped through is a player
    {
    //...
    }
    VisualObject.cpp:
    Code:
    VisualObject::VisualObject(const std::string& filename) :
    		BaseObject(),
    		surface(NULL),
    		x(0),
    		y(0),
    		objectType(1) // identifies it as a VisualObject
    {
    // ...
    }
    BaseObject.cpp:
    Code:
    BaseObject::BaseObject() :
    	objectType(0)
    {
    // ...
    }
    Any ideas?

  2. #2
    Join Date
    Apr 1999
    Posts
    27,449

    Re: Polymorphism; How to get the specific class?

    Quote Originally Posted by dwdude View Post
    The thing is, I am currently looping through a list of BaseObjects (which get added to the list when I create an instance of the Player or VisualObject class) and trying to find out if the object I have looped into is a Player class. That part is simple; I have been able to identify which BaseObject in the list corresponds to a Player object.
    That sounds like it defeats the purpose of polymorphism. The base class isn't supposed to know about who is derived from it.

    Nowhere do you mention virtual functions. Virtual functions are the thing that makes the difference between true polymorphism, and just a fancy way of doing basic procedural, non-OO coding. Maybe you should rethink your design, especially if your design does not adhere to the IS-A principle of public inheritance (derived class IS-A base class).

    Regards,

    Paul McKenzie
    Last edited by Paul McKenzie; January 21st, 2010 at 09:50 PM.

  3. #3
    Join Date
    Jan 2010
    Posts
    3

    Re: Polymorphism; How to get the specific class?

    I was hoping the use of virtual functions was assumed

    Perhaps it's not true, pure polymorphism. It's not so much of the BaseObject needing to know what class derives from it as it is for another class to know. Is there any way to do so?

  4. #4
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Polymorphism; How to get the specific class?

    The notion of a BaseObject which *everything* inherits from doesn't fit the C++ paradigm very well. It's really more of a Java concept. You should consider whether or not it's really necessary here. What does having that BaseObject get for you?

  5. #5
    Join Date
    Jan 2010
    Posts
    3

    Re: Polymorphism; How to get the specific class?

    Quote Originally Posted by Lindley View Post
    The notion of a BaseObject which *everything* inherits from doesn't fit the C++ paradigm very well. It's really more of a Java concept. You should consider whether or not it's really necessary here. What does having that BaseObject get for you?
    Not everything inherits the BaseObject class; Just VisualObject class, my player class, and a (soon to be) enemy class.

    The usage of the BaseObject in this instance helps with the drawing of those entities to the screen in an orderly, manageable fashion. Looping through a list of BaseObjects, calling their move functions, collision detecting functions, and draw functions in a few lines of simple code sounds like KISS to me.

  6. #6
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401

    Re: Polymorphism; How to get the specific class?

    The problem you are describing fits the visitor pattern. Here is in a nutshell how it would work for your example:
    Code:
    #include <iostream>
    
    class Tilemaster;
    
    class BaseObject {
    public:
      virtual void accept(Tilemaster& t);
    };
    
    class Player : public BaseObject {
    public:
      virtual void accept(Tilemaster& t);
      void setPos(int x, int y) { std::cout << "Move to " << x << "," << y << std::endl; }
    };
    
    class Tilemaster {
    public:
      void movePlayer(BaseObject& obj) { /* move if object is player */ obj.accept(*this); }
      void visit(BaseObject& obj) { /* do nothing */ }
      void visit(Player& obj) { obj.setPos(42,24);}
    };
    
    inline
    void BaseObject::accept(Tilemaster& t) {t.visit(*this);}
    inline
    void Player::accept(Tilemaster& t) {t.visit(*this);}
    
    int main() {
      Tilemaster t;
    
      BaseObject* obj1 = new BaseObject(); // or any other subclass
      t.movePlayer(*obj1); //nothing happening
    
      BaseObject* obj2 = new Player();
      t.movePlayer(*obj2); // obj2.setPos being called
    
      delete obj1;
      delete obj2;
    }
    More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity. --W.A.Wulf

    Premature optimization is the root of all evil --Donald E. Knuth


    Please read Information on posting before posting, especially the info on using [code] tags.

  7. #7
    Join Date
    Apr 2007
    Location
    Mars NASA Station
    Posts
    1,436

    Re: Polymorphism; How to get the specific class?

    Why the problem fit for visitor pattern ?

    Thanks.
    Thanks for your help.

  8. #8
    Join Date
    May 2009
    Posts
    2,413

    Re: Polymorphism; How to get the specific class?

    Quote Originally Posted by Lindley View Post
    The notion of a BaseObject which *everything* inherits from doesn't fit the C++ paradigm very well. It's really more of a Java concept.
    What's this "C++ paradigm" you're referring to? I've never heard about it. Is it something you've invented yourself?

    Do you mean that C++ rules out certain OO designs? I've never heard of that either.

  9. #9
    Join Date
    May 2009
    Posts
    2,413

    Re: Polymorphism; How to get the specific class?

    Quote Originally Posted by Peter_APIIT View Post
    Why the problem fit for visitor pattern ?
    The Visitor pattern is based on a so called double dispatch. It's an OO technique to ask objects what derived class they are. It's a typesafe downcast if you will.

    And this is what the OP wants. He has a bunch of derived objects known only by their common base class. Now he wants each of them to reveal its actual derived class (so he can call methods present in the derived classes).

    In my view the Visitor patterns generally is overused and thrown in as a sort of Swiss knife to fix all sorts of flawed designs where polymorphism and interface inheritance haven't been properly used.
    Last edited by nuzzle; January 22nd, 2010 at 10:41 AM.

  10. #10
    Join Date
    May 2009
    Posts
    2,413

    Re: Polymorphism; How to get the specific class?

    Quote Originally Posted by dwdude View Post
    The part I'm having trouble with is that I have another class, TileMaster, who wants to change the coordinates of the instance of the player identified through the previous loop, but the BaseObject class doesn't have x or y variables, but the Player (and VisualObject) do.
    The question then is: Why doesn't BaseObject have x and y variables? Or alternatively, why do Player and VisualObject have x and y variables?

    In a polymorphic design the base class must "cover" for all its intended derived classes. This means code written using base class variables should work regardless of which derived object is plugged in. With a fancy name this is called the Liskov substitution principle and you're breaking it so you don't have a valid polymorphic design.
    Last edited by nuzzle; January 22nd, 2010 at 10:34 AM.

  11. #11
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Polymorphism; How to get the specific class?

    Quote Originally Posted by nuzzle View Post
    What's this "C++ paradigm" you're referring to? I've never heard about it. Is it something you've invented yourself?

    Do you mean that C++ rules out certain OO designs? I've never heard of that either.
    It's another way of saying "Don't try to write C++ as if it were Java. There are often better approaches." But you know that, you're just being pedantic.
    Last edited by Lindley; January 22nd, 2010 at 10:56 AM.

  12. #12
    Join Date
    Jan 2004
    Location
    Düsseldorf, Germany
    Posts
    2,401

    Re: Polymorphism; How to get the specific class?

    Quote Originally Posted by nuzzle View Post
    The question then is: Why doesn't BaseObject have x and y variables? Or alternatively, why do Player and VisualObject have x and y variables?

    In a polymorphic design the base class must "cover" for all its intended derived classes.
    When designing a class, one typically does not know yet, what specializations of the class will emerge later in the design process (one of the fundamental principles of OO as it allows extendibility). So a base class cannot "cover" (whatever that means) for all derived classes.
    Quote Originally Posted by nuzzle View Post
    This means code written using base class variables should work regardless of which derived object is plugged in. With a fancy name this is called the Liskov substitution principle and you're breaking it so you don't have a valid polymorphic design.
    The Liskov substitution principle states that derived class objects must behave correctly when used as base class objects (the opposite of what you state above). Adding variables and methods to derived classes does not at all break this principle.

    The problem in the OP's design is of different nature: The code iterates over a vector of BaseObject pointers, while it should iterate only over the VisualObjects. Keeping those in a separate vector from the beginning (or completely abandoning the concept of the BaseObject) would probably be the best solution.

    Quote Originally Posted by nuzzle View Post
    In my view the Visitor patterns generally is overused and thrown in as a sort of Swiss knife to fix all sorts of flawed designs where polymorphism and interface inheritance haven't been properly used.
    Overuse of the pattern is usually a sign for a too deep class hierarchy, i.e. inheritance having been used where it should not be. Trying to solve this with polymorphism easily leads to bloated base classes with a lot of virtual methods that only make sense for some derived classes. If I have to chose between those two alternatives, I chose the visitor pattern.
    More computing sins are committed in the name of efficiency (without necessarily achieving it) than for any other single reason - including blind stupidity. --W.A.Wulf

    Premature optimization is the root of all evil --Donald E. Knuth


    Please read Information on posting before posting, especially the info on using [code] tags.

  13. #13
    Join Date
    May 2009
    Posts
    2,413

    Re: Polymorphism; How to get the specific class?

    Quote Originally Posted by Lindley View Post
    It's another way of saying "Don't try to apply the principals you may have learned in Java directly to C++. There are often better alternatives." But you know that, you're just being pedantic.
    Sure, just because both Java and C# use an implicit top class doesn't mean the first thing you should do in C++ is to mimic that and introduce an Object class all your other classes inherit. I fully agree with that.

    What I have problems with is when it's suggested that it somehow goes against the very nature of C++ to use a common top class. Nothing could be more wrong. If you think your design would benefit from a top class then C++ doesn't stand in your way. In fact the virtual inheritance mechanism makes it quite straightforward to have one.
    Last edited by nuzzle; January 22nd, 2010 at 11:15 AM.

  14. #14
    Lindley is offline Elite Member Power Poster
    Join Date
    Oct 2007
    Location
    Seattle, WA
    Posts
    10,895

    Re: Polymorphism; How to get the specific class?

    I have nothing against base classes, or even deep hierarchies when appropriate.

    But if you derive everything from a single class, then there must be some virtual method or property that every object in your design needs to possess. Otherwise, it's fairly pointless. That isn't impossible, but it seems like it would be fairly rare.

    If you're just looking to be able to store arbitrary objects together and recover them later via a cast, then something like boost::any would probably be more appropriate.

  15. #15
    Join Date
    May 2009
    Posts
    2,413

    Re: Polymorphism; How to get the specific class?

    Quote Originally Posted by treuss View Post
    When designing a class, one typically does not know yet, what specializations of the class will emerge later in the design process (one of the fundamental principles of OO as it allows extendibility). So a base class cannot "cover" (whatever that means) for all derived classes.
    In polymorphic design you start out with an abstraction in the form of a base class. The base class defines a type (essentially the public methods and their behavior). Any derived class must abide (in the Liskov sense) with the base class type. You can change anything anytime during a design process - except that.

    Extensions to a polymorphic design is according to the Open/Closed principle. When you "plug in" a new derived class it will work "seamlessly" with existing code. This is what OO extendibility is about. Mere creating a derived class or adding a method to an existing one is not.
    Last edited by nuzzle; January 24th, 2010 at 03:42 AM.

Page 1 of 2 12 LastLast

Tags for this Thread

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured