By JonnFranMore


2019-03-11 06:23:40 8 Comments

I tried to create an array Entity[] with elements Human and Zomby.

Entity ent[5];
ent[0].set("human");
ent[1].set("human");
ent[2].set("human");
ent[3].set("human");
ent[4].set("zomby");

or

Entity ent[5];
ent[0] = new Human();
ent[1] = new Human();
ent[2] = new Human();
ent[3] = new Zomby();
ent[4] = new Zomby();
delete[] ent;

They are in different classes because Human and Zomby need different ai functions. They are in the same array to compare them, like this:

for (int a = 0; a < entL; a++)
{
    for (int b = 0; b < entL; b++)
    {
        ent[a].ai( ent[b] ); // process ai interaction with other entities
    }
}

Is there a way for an array to have multiple types, or is there a better way to handle objects? Here's my example code:

class Entity // base class
{
public:
    float x, y;
};

class Human : public Entity // sub-class
{
public:
    void ai(Entity &n){}
};
class Zomby : public Entity // sub-class
{
public:
    void ai(Entity &n) {}
};

int main(int argc, char **argv)
{
    // create entities in one container
    const int entL = 5;
    Entity ent[entL];
    ent[0] = new Human();
    ent[1] = new Human();
    ent[2] = new Zomby();
    ent[3] = new Zomby();
    ent[4] = new Zomby();

    // inside game while-loop
    for (int a = 0; a < entL; a++)
    {
        for (int b = 0; b < entL; b++)
        {
            ent[a].ai( ent[b] ); 
        }
    }

    delete[] ent;

    system("PAUSE");
    return 0;
}

RESOLVED

I can make variants of functions in sub-classes like ai using virtual and override.

class Entity // base class
{
public:
    Position pos;
    virtual void ai(Position& other) { }

};

class Human : public Entity // sub-class
{
public:
    virtual void ai(Position& other) override {
        // human-specific AI code
    }
};

class Zomby : public Entity // sub-class
{
public:
    virtual void ai(Position& other) override {
        // zomby-specific AI code
    }
};

Entity* ent[5];
ent[0] = new Human (); // set sub-class elements
ent[1] = new Zomby ();
ent[2] = new Zomby ();
ent[3] = new Zomby ();
ent[4] = new Zomby ();

ent[0]->ai(ent[1]->pos); // call human.ai() passing zomby.pos

delete[]* ent;

Now, an array-pointer of a base-class can store elements of sub-classes.

2 comments

@Philipp 2019-03-11 12:18:42

When you have an array of type Entity then you can only call methods on the entries which are declared in the class Entity.

If you want Human and Zomby to have different implementations for that method, then you can declare that function as virtual in the Entity class. You can then override that implementation in both sub-classes. That means when you call the method .ai on an Entity the program checks what kind of entity it is and calls the corresponding method of the corresponding class.

Another thing you might want to consider is to pass the argument by reference instead of by value. When you pass objects by value, then you are creating a copy of the object in memory, pass that copy to the function and then discard that copy when the function finishes. But when you pass objects by reference, you are passing that object. This has two advantages:

  1. it's faster because the program doesn't need to create a copy of the object.
  2. You can do changes to the object in the function which are applied to the original object.

Example:

class Entity // base class
{
public:
    float x, y;
    virtual void ai(Entity& other) { }

};

class Human : public Entity // sub-class
{
public:
    virtual void ai(Entity& other) override {
           // human-specific AI code
    }
};

class Zomby : public Entity // sub-class
{
public:
    virtual void ai(Entity& other) override {
           // zomby-specific AI code
    }
};

@JonnFranMore 2019-03-11 15:23:23

This may work. If I use a pointer array of base-class and set each element to sub-class I can call sub-class overridden functions from the array. The new and delete keywords may also be necessary.

@Jay 2019-03-11 07:28:23

In this case you want to use virtual functions on the base class like so:

class Entity // base class
{
  virtual void ai(Entity n){}
}

Even though this is just example code, I can see that it might cause problems because you are passing by value instead of by reference.

@Jack Aidley 2019-03-11 13:51:21

In this case, surely virtual void ai(Entity n) = 0; is appropriate?

@Jay 2019-03-11 14:09:55

I would consider that an implementation detail, whether to use a virtual or pure virtual function. This is a good option but the requirements aren't exacty clear.

Related Questions

Sponsored Content

2 Answered Questions

2 Answered Questions

[SOLVED] Read function outside of code while run-time?

1 Answered Questions

[SOLVED] Detecting Overlapping Shapes

1 Answered Questions

[SOLVED] How to Design a Generic Collision Detection System?

1 Answered Questions

[SOLVED] C++ read access violation when deleting object

  • 2018-01-06 05:56:23
  • codelyoko373
  • 873 View
  • 0 Score
  • 1 Answer
  • Tags:   c++

2 Answered Questions

2 Answered Questions

[SOLVED] Lua Implementation

  • 2014-07-20 10:00:12
  • KKlouzal
  • 1042 View
  • 5 Score
  • 2 Answer
  • Tags:   lua c++

1 Answered Questions

[SOLVED] DirectX particle system. ConstantBuffer

1 Answered Questions

[SOLVED] Collision Shapes Abstraction Design

3 Answered Questions

[SOLVED] Question on the implementation of my Entity System

Sponsored Content