-2

I could not think of a better name.

I have a class called MoveObjects which holds position and move info.

Then I have two classes, Items and Attacks. Both have MoveObjects in common.

What I am trying to do, is loop through move objects and the loop determine if it is associated with a Item or Attack.

Basically (but can't do it this way)

// Classes, boiled down, looks like:

  MoveObjects {
    int x;
    int y;
  };

  Items {
    string name;
    int buff;
    int cost;
    int img_id;
  };

  Attack {
    int owner;
    int strength;
    int speed;
  };


// Polymorphism boiled down

  class Item : public MoveObjects

  class Attack : public MoveObjects


// pseudo loop

  for (int i = 0; i < MoveObjects.size; i++) {

    // if item

    // if attack

  }
  • Try to look up "virtual methods" – hoffmale Jul 15 '16 at 21:08
  • @hoffmale I read up on that and looked at example code. I updated what my code looks like, boiled down, to show how different "items" and "attacks" are. Is virtual methods still the way to go? – Evan Carslake Jul 15 '16 at 22:07
  • For your use case, it should suffice declaring a virtual method on MoveObjects that gets overridden by Item and Attack. you can then call that method in the loop on MoveObjects instances, and the compiler resolves those calls to the correct method. – hoffmale Jul 15 '16 at 22:25
  • @hoffmale thanks. I have been trying to wrap my head around this, and can't figure out how to write this. So in MoveObjects what should the virtual function do? I keep thinking position... but that's not right. I'm confused, the only way I see it is making both a virtual Item and virtual attack in MoveObjects... that is definitely not right... – Evan Carslake Jul 16 '16 at 0:46
  • 1
    If you desire an answer which is more suitable for soft real-time games, you may want to visit the Gamedev StackExchange. – Lars Viklund Jul 16 '16 at 8:12
2

(I'm writing this as an answer since it's too long for a comment)

Here's a sample layout for using virtual methods to solve your problem:

class MoveObjects {
public:
    virtual void doSomething() = 0; // declare a method name
    // other members of MoveObjects
};

class Item : public MoveObjects {
public:
    virtual void doSomething() {
        // insert Item-specific code here
    }
    // other Item members
};

class Attack : public MoveObjects {
public:
    virtual void doSomething() {
        // insert Attack-specific code here
    }
};

Basically, you declare a method in MoveObjects called doSomething() and specify that it will be implemented in the derived classes (in this case, Item and Attack).

In the for loop (assuming moveObjects is of type std::vector<MoveObjects*> or similar) you just call doSomething() on the base class, which then redirects to the actual implementation of the doSomething() method of the corresponding type (Item::doSomething() for objects of type Item, Attack::doSomething() for objects of type Attack):

for(int i = 0; i < moveObjects.size(); i++) {
    moveObjects[i]->doSomething();
}
  • one last question. Would it be bad practice to do something like: GetObjectType(), returning an enum like, "Item, Attack, Enemy". Then having virtual pointers as: virtual Item* GetItemPtr(); virtual Attack* GetAttackPtr(); virtual Coin* GetCoinPtr(). Setting all three NULL by default, and when used, add the pointer to its type? (Ex: So if GetObjectType() is Item, GetItemPtr() will point to an Item, leaving Attack and Coin still NULL) – Evan Carslake Jul 16 '16 at 13:09
  • 1
    @EvanCarslake Look up "tell, don't ask". GetObjectType() breaks encapsulation. Rather than just calling doSomething() now MoveObjects has to have knowledge of what's being moved. It must test every case of an enum. It may require access to other internal information in Item, Attack, or Enemy objects. Now you can't add "Goal, Heal, Friend" without having to make changes in previously tested code. That violates the open-closed principle. You'll probably see a lot of procedural code that violates these principles in your time. Study the principles to learn the cost this comes at. – candied_orange Jul 16 '16 at 13:55
  • @CandiedOrange definitely looking up. Also, I didn't know GetObjectType() was already a function. I was thinking of making my own like: enum MOVEOBJ_TYPE { MOVEOBJ_ITEM, MOVEOBJ_ATTACK } and a MOVEOBJ_TYPE GetMoveObjectType() I also read that the pointers would not be virtual (no such thing.) So essentially I would have all NULL pointers, except the one pointing to its "move object type." – Evan Carslake Jul 16 '16 at 14:01
  • @Evan I could design a house with 3 outside doors. When the house is clean you go in door number 1. If you go in 2 or 3 you get burned to death. If it's dirty you go in door number 2. If you go into 1 or 3 you get burned to death. If the house is cluttered you go in 3. 1 or 2 will burn you to death. Now sure, we could install windows and peep holes so you have a better than 1/3rd chance to live but does this sound like a good way to design a house? – candied_orange Jul 16 '16 at 14:10
  • @CandiedOrange yeah you're exactly right. I ended up putting it on paper and realizing that my idea would completely defeat the purpose of virtual functions. – Evan Carslake Jul 17 '16 at 17:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.