Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
CODE PROJECT For Those Who Code
  • Home
  • Articles
  • FAQ
Community
  1. Home
  2. General Programming
  3. C / C++ / MFC
  4. Polymorphic pointer points to what?

Polymorphic pointer points to what?

Scheduled Pinned Locked Moved C / C++ / MFC
game-devgraphicsquestionlearning
21 Posts 7 Posters 0 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S SimonSays

    Well, as earlier posters have pointed out, dynamic_cast and typeid can be used to extract the information you want. However, to me at least, when you need to do this (and presumably frequently for an astroids game) you might start asking if you have the best possible design. I kind of liked the suggestion of the eariler poster about adding a function like "virtual bool ResolveColision (baseClass *)". Otherwise you could have a huge ugly mess of collision resolution between any 2 possible object types. If you happen to just need to be able to get set of all asteroids in the game, why not keep around an extra container just for astroids (and one for ships, missles, etc). Then you can iterate through any specific object without messing with all the other object types you are not interested in.

    G Offline
    G Offline
    G_urr_A
    wrote on last edited by
    #12

    I've ended up using typeid now. And of course I'm using the best possible design. Not. It's grown slightly too messy for my tastes by now, and it'll probably get worse. The whole thing is a school project in which I have to cooperate with another guy. We've implemented support in some places for features that haven't been implemented, we did not think everything through before we started writing, and we don't really share a common concept of what OO is, so the code is quite messy. I'd love to rewrite the whole thing, but we're expected to present the stuff to our teacher this friday, and we're expected to understand all the code (he needs to understand "my parts"), and he's out of town, coming back thursday evening. So, a rewrite isn't an option right now. But, thanks a lot to everyone for the input! We got my problem solved, and I got some other good info on what not to do next time. Now I just need to finnish this stuff...

    G 1 Reply Last reply
    0
    • G G_urr_A

      I've ended up using typeid now. And of course I'm using the best possible design. Not. It's grown slightly too messy for my tastes by now, and it'll probably get worse. The whole thing is a school project in which I have to cooperate with another guy. We've implemented support in some places for features that haven't been implemented, we did not think everything through before we started writing, and we don't really share a common concept of what OO is, so the code is quite messy. I'd love to rewrite the whole thing, but we're expected to present the stuff to our teacher this friday, and we're expected to understand all the code (he needs to understand "my parts"), and he's out of town, coming back thursday evening. So, a rewrite isn't an option right now. But, thanks a lot to everyone for the input! We got my problem solved, and I got some other good info on what not to do next time. Now I just need to finnish this stuff...

      G Offline
      G Offline
      G_urr_A
      wrote on last edited by
      #13

      Hmm.... Since I've already started a thread, I guess I might as well put it to good use... ;-) I've implemented an ugly hack now. In the code where I give bullets their position and speed, I first find the ship that fired them in ObjectList (which is the vector of *base_class that I've mentioned), then get some data from the ship object. The thing is, I need to access methods that are specific to the CShip class, but I've only got a pointer to base_class to handle it. What I do now is the following: CShip *temp; temp = (CShip*)(void*)ObjectList.at(i); I cast to void* and then to the data type I need. Anything but this explicit casting produces errors, since the compiler doesn't realize that I've checked (using typeid) that what I'm handling is really a CShip object. This solution is really ugly, IMO. There should be a good way to do this, but I can't figure it out (I'm kind of new to OO).

      S 1 Reply Last reply
      0
      • G G_urr_A

        Hmm.... Since I've already started a thread, I guess I might as well put it to good use... ;-) I've implemented an ugly hack now. In the code where I give bullets their position and speed, I first find the ship that fired them in ObjectList (which is the vector of *base_class that I've mentioned), then get some data from the ship object. The thing is, I need to access methods that are specific to the CShip class, but I've only got a pointer to base_class to handle it. What I do now is the following: CShip *temp; temp = (CShip*)(void*)ObjectList.at(i); I cast to void* and then to the data type I need. Anything but this explicit casting produces errors, since the compiler doesn't realize that I've checked (using typeid) that what I'm handling is really a CShip object. This solution is really ugly, IMO. There should be a good way to do this, but I can't figure it out (I'm kind of new to OO).

        S Offline
        S Offline
        Stephen Hewitt
        wrote on last edited by
        #14

        If you must use this technique use dynamic_cast instead. This design is poor: using a downcast is rarely needed and you should use virtual function instead. Steve

        1 Reply Last reply
        0
        • C Cedric Moonen

          What do you mean by switching ? Here, there is no casting involved: suppose you have a ResolveCollision function (and you pass the object with which it collides as parameter) that is virtual in the base class, and each child class overrides this method. In these particular functions, you need to know at least what is the type of the other object you are colliding with (because the actions to be taken will be different depending of the type of the other object). What suggestion do you have for a better design ? I'm curious now :).


          Cédric Moonen Software developer
          Charting control

          S Offline
          S Offline
          Stephen Hewitt
          wrote on last edited by
          #15

          Cedric Moonen wrote:

          add a variable in the base_class that specify which kind of object it is

          This is what I was referring to in my comment. This article[^] can expliain why I think its probably a bad idea better then I can here. The section on The Open Closed Principle is about such designs and why they're a bad idea. Steve

          C 1 Reply Last reply
          0
          • S Stephen Hewitt

            Cedric Moonen wrote:

            add a variable in the base_class that specify which kind of object it is

            This is what I was referring to in my comment. This article[^] can expliain why I think its probably a bad idea better then I can here. The section on The Open Closed Principle is about such designs and why they're a bad idea. Steve

            C Offline
            C Offline
            Cedric Moonen
            wrote on last edited by
            #16

            Hi Stephen, thanks for the article, it was interesting. I totally agree with you on that point but here, a part of the problem is solved by using a virtual ResolveCollision function. Still, there is a need to know with which entity the current entity is colliding with. So, typically what you suggest is the use of RTTI (getting the typeid of the class) ? This will 'separate' the base class from the implementations (a enum in the base class is not required anymore). Is that what you were thinking about ? Thanks for your answer ;) PS: if I'm so interested, it's because I also develop a game in this style and I implemented in the way I described above. But I'm open to better suggestions :-D


            Cédric Moonen Software developer
            Charting control

            S 1 Reply Last reply
            0
            • C Cedric Moonen

              Hi Stephen, thanks for the article, it was interesting. I totally agree with you on that point but here, a part of the problem is solved by using a virtual ResolveCollision function. Still, there is a need to know with which entity the current entity is colliding with. So, typically what you suggest is the use of RTTI (getting the typeid of the class) ? This will 'separate' the base class from the implementations (a enum in the base class is not required anymore). Is that what you were thinking about ? Thanks for your answer ;) PS: if I'm so interested, it's because I also develop a game in this style and I implemented in the way I described above. But I'm open to better suggestions :-D


              Cédric Moonen Software developer
              Charting control

              S Offline
              S Offline
              Stephen Hewitt
              wrote on last edited by
              #17

              I would not use any type of RTTI. First I'd think about the game. For example with collision detection in asteroids the following should be noted:  - Asteroids don't collide with each other.  - Bullets don't collide with each other. These facts mean we don't have to check every pair of objects for collisions: we only need to test for the following collisions:  - Bullets with asteroids.  - Bullets with the enemy ships.  - Asteroids with asteroids.  - Your ship with asteroids.  - Your ship with bullets.  - Your ship with enemy ship. These distinctions should be reflected in our design to minimize the amount of work we need to do to detect collisions. I haven't thought it through, but I'd probably use multiple lists instead on one super list. Steve

              C 1 Reply Last reply
              0
              • S Stephen Hewitt

                I would not use any type of RTTI. First I'd think about the game. For example with collision detection in asteroids the following should be noted:  - Asteroids don't collide with each other.  - Bullets don't collide with each other. These facts mean we don't have to check every pair of objects for collisions: we only need to test for the following collisions:  - Bullets with asteroids.  - Bullets with the enemy ships.  - Asteroids with asteroids.  - Your ship with asteroids.  - Your ship with bullets.  - Your ship with enemy ship. These distinctions should be reflected in our design to minimize the amount of work we need to do to detect collisions. I haven't thought it through, but I'd probably use multiple lists instead on one super list. Steve

                C Offline
                C Offline
                Cedric Moonen
                wrote on last edited by
                #18

                Stephen Hewitt wrote:

                I haven't thought it through, but I'd probably use multiple lists instead on one super list.

                Mmmhh, I see a big restriction in that way of thinking: what happens if you want to add a new entity type, say 'bonus' (that gives you lives or new weapon) ? Then, you got a problem in your design because you have to manage a new list which can result in a lot of changes in the existing code... Right now, what we are doing is that we have a factory that can create specific entities. The different entities register themselves in the factory at the program startup (in fact they register their name and a function that create one instance of the entity, so no need to modify the factoty when new entities are added, it's just map names to a creation function). So, if you want to create a new entity type, you just have to create the new class (and the creation function) and register it in the factory at startup and that's done ! No modifications in the rest of the code. You will tel me: 'Ok, but to be used, these new entites needs to be created so you need to know if they exist or not'. In fact this step is not 'directly' required because the creation of the levels of the game is made through an editor. The editor retrieves the available entities from the factory and allow the end user to place them in the level (so, there also, there is no need to know these entities). With your design, I see a flaw when you want to add new entity types that were not planned.

                Stephen Hewitt wrote:

                These distinctions should be reflected in our design to minimize the amount of work we need to do to detect collisions.

                It's perfectly doable with the method I exposed you: in the ResolveCollision of each entity type, it's up to you to take action on one or several 'collisions type' PS: I don't want to prove you're wrong, but this is an interesting debate and I'm interested in your opinion.


                Cédric Moonen Software developer
                Charting control

                S 1 Reply Last reply
                0
                • C Cedric Moonen

                  Stephen Hewitt wrote:

                  I haven't thought it through, but I'd probably use multiple lists instead on one super list.

                  Mmmhh, I see a big restriction in that way of thinking: what happens if you want to add a new entity type, say 'bonus' (that gives you lives or new weapon) ? Then, you got a problem in your design because you have to manage a new list which can result in a lot of changes in the existing code... Right now, what we are doing is that we have a factory that can create specific entities. The different entities register themselves in the factory at the program startup (in fact they register their name and a function that create one instance of the entity, so no need to modify the factoty when new entities are added, it's just map names to a creation function). So, if you want to create a new entity type, you just have to create the new class (and the creation function) and register it in the factory at startup and that's done ! No modifications in the rest of the code. You will tel me: 'Ok, but to be used, these new entites needs to be created so you need to know if they exist or not'. In fact this step is not 'directly' required because the creation of the levels of the game is made through an editor. The editor retrieves the available entities from the factory and allow the end user to place them in the level (so, there also, there is no need to know these entities). With your design, I see a flaw when you want to add new entity types that were not planned.

                  Stephen Hewitt wrote:

                  These distinctions should be reflected in our design to minimize the amount of work we need to do to detect collisions.

                  It's perfectly doable with the method I exposed you: in the ResolveCollision of each entity type, it's up to you to take action on one or several 'collisions type' PS: I don't want to prove you're wrong, but this is an interesting debate and I'm interested in your opinion.


                  Cédric Moonen Software developer
                  Charting control

                  S Offline
                  S Offline
                  Stephen Hewitt
                  wrote on last edited by
                  #19

                  We'll stick with asteroids as that's the original topic. My original comment was against switching on object type, be it by using typeid, dynamic_cast or an enum in a base class. I don't think I need to go over this further given that the article I posted a link to explains it better than I could. Now let’s get to the collision detection. As I pointed out you need not check for collisions between every pair of object as; for example, bullets can't collide with each other. If you've got n objects there are (n*(n-1))/2 = (n^2-n)/2 pairs to test: so it's probably a good idea to limit the size on n since the growth is quadratic. I admit in a game of asteroids, with today’s computers, you probably need not worry. I would probably use multiple lists as not every aspect of an objects behavior need be determined by it: some aspects can be controlled by its environment. For example, which container it's listed in. This need not be a limitation as you control which objects are added to which lists. I don't want to get into too much of a debate however, as a lot of this is all theoretical. To really get into it we would need a concrete example to work with and spend some time analyzing it and then contrast different implementation strategies; that's a lot of work to win an argument. Steve

                  C 1 Reply Last reply
                  0
                  • S Stephen Hewitt

                    We'll stick with asteroids as that's the original topic. My original comment was against switching on object type, be it by using typeid, dynamic_cast or an enum in a base class. I don't think I need to go over this further given that the article I posted a link to explains it better than I could. Now let’s get to the collision detection. As I pointed out you need not check for collisions between every pair of object as; for example, bullets can't collide with each other. If you've got n objects there are (n*(n-1))/2 = (n^2-n)/2 pairs to test: so it's probably a good idea to limit the size on n since the growth is quadratic. I admit in a game of asteroids, with today’s computers, you probably need not worry. I would probably use multiple lists as not every aspect of an objects behavior need be determined by it: some aspects can be controlled by its environment. For example, which container it's listed in. This need not be a limitation as you control which objects are added to which lists. I don't want to get into too much of a debate however, as a lot of this is all theoretical. To really get into it we would need a concrete example to work with and spend some time analyzing it and then contrast different implementation strategies; that's a lot of work to win an argument. Steve

                    C Offline
                    C Offline
                    Cedric Moonen
                    wrote on last edited by
                    #20

                    Stephen Hewitt wrote:

                    I don't think I need to go over this further given that the article I posted a link to explains it better than I could.

                    Yes sure,I agree. Thanks for article though.

                    Stephen Hewitt wrote:

                    If you've got n objects there are (n*(n-1))/2 = (n^2-n)/2 pairs to test: so it's probably a good idea to limit the size on n since the growth is quadratic.

                    I solved this in another way: there are only three "teams": players (ship and bullets), ennemies (ships and bullets) and neutral (bonus, and other things that doesn't have any impact on the game). So, basically this reduce a lot the pairs of collisions. And anyway these 'Resolving collisions' are done in the derived classes themselves (so, you can neglected certain pairs).

                    Stephen Hewitt wrote:

                    I don't want to get into too much of a debate however, as a lot of this is all theoretical

                    Yes sure. But anyway thanks for exposing your point of vue :). I find this always interesting to see how other programmers solve design 'problems' (that's what I'm doing here also, just showing you how I do that, absolutely not saying that it's the best solution :rolleyes:). But I agree with you, we won't dig into more details as it requires a concrete example and some time to spend on it.


                    Cédric Moonen Software developer
                    Charting control

                    S 1 Reply Last reply
                    0
                    • C Cedric Moonen

                      Stephen Hewitt wrote:

                      I don't think I need to go over this further given that the article I posted a link to explains it better than I could.

                      Yes sure,I agree. Thanks for article though.

                      Stephen Hewitt wrote:

                      If you've got n objects there are (n*(n-1))/2 = (n^2-n)/2 pairs to test: so it's probably a good idea to limit the size on n since the growth is quadratic.

                      I solved this in another way: there are only three "teams": players (ship and bullets), ennemies (ships and bullets) and neutral (bonus, and other things that doesn't have any impact on the game). So, basically this reduce a lot the pairs of collisions. And anyway these 'Resolving collisions' are done in the derived classes themselves (so, you can neglected certain pairs).

                      Stephen Hewitt wrote:

                      I don't want to get into too much of a debate however, as a lot of this is all theoretical

                      Yes sure. But anyway thanks for exposing your point of vue :). I find this always interesting to see how other programmers solve design 'problems' (that's what I'm doing here also, just showing you how I do that, absolutely not saying that it's the best solution :rolleyes:). But I agree with you, we won't dig into more details as it requires a concrete example and some time to spend on it.


                      Cédric Moonen Software developer
                      Charting control

                      S Offline
                      S Offline
                      Stephen Hewitt
                      wrote on last edited by
                      #21

                      Cedric Moonen wrote:

                      I solved this in another way: there are only three "teams": players (ship and bullets), ennemies (ships and bullets) and neutral (bonus, and other things that doesn't have any impact on the game).

                      If you make a list of objects in each "team" you’re left with a similar architecture to what I was suggesting. Having a list for the members of each of the team means you can visit the members of a team without visiting every object in the "world". Steve

                      1 Reply Last reply
                      0
                      Reply
                      • Reply as topic
                      Log in to reply
                      • Oldest to Newest
                      • Newest to Oldest
                      • Most Votes


                      • Login

                      • Don't have an account? Register

                      • Login or register to search.
                      • First post
                        Last post
                      0
                      • Categories
                      • Recent
                      • Tags
                      • Popular
                      • World
                      • Users
                      • Groups