Question

I'm a beginner programmer in C++ and making my first 2d game (just for learning basic's of the language, I'm not planning anything big :P). And I have my first problem on which I couldn't find a solution on the internet: There is one, main class for entities:

class entity
{
   //something there
};

And some derived classes for concrete monsters, player etc.

class zombie : public entity
{
  //...
};
class mutant : public entity
...
class player : public entity
...

Now the problem is how to make one array (or some container/anything) for all the types of entities? I mean if all monsters and player objects were from class "entity", making for example, collision would be simple:

std::vector<entity> entityTbl;
entityTbl.push_back( entity(...) );
...
entityTbl.push_back( entity(...) );

for(int i=0;i<entityTbl.end();i++)
  for(int k=0;k<entityTbl.end();k++)
    entityTbl[i].collision(entityTbl[k]); //some collision function

But how should I check those collision in simple way (I mean in one array/container) if I have different objects of types "zombie", "mutant", "player"...? In this situation I can't use "entity" container anymore, for 2 reasons:

  1. I would like "class entity" to be abstract
  2. If I use this container to make for example player object, I can't use functions which are in "class player".

I hope you will understand what I mean. :) Thanks in advice for help and sorry for any language mistakes - english is not my native lang.

Was it helpful?

Solution

You can't have instances of abstract classes. Instead as of your sample does, try the following:

 std::vector<std::shared_ptr<entity> > entityTbl;
 entityTbl.push_back( new zombie(...) );     
 entityTbl.push_back( new mutant(...) );

Since the above sample will only work with , as a fallback solution you can use

 std::vector<entity*> > entityTbl;

Code to fill the table is the same. But you'll need to delete the items from entityTbl, before it's destructed (goes out of scope):

 for(std::std::vector<entity*> >::iterator it = entityTbl.begin(); 
     it != entityTbl.end();
     ++it) {
     delete *it;
 }

OTHER TIPS

an attempt to have abstract class object will occur an error, as you tried to do in your code. What you can have is a pointer to the abstract class (in your case - entity). Pointers to base classes can point to derived classes. for example:

class base {
public: virtual void func() = 0;
};

class derived : public virtual base {
    void func() override { std::cout << "\"base\" type pointer, but pointing to \"derived\"." << '\n'; }
};
int main()
{
    base *basep;
    basep = new derived;
    basep->func();
    system("PAUSE");
    return EXIT_SUCCESS;
}

Btw, In your loop, i is an int, which isn't the return value of vector::end(). end() is a function that return an iterator type iterators are pointers-like objects generated by STL container member functions. i'd suggest you to modify your loop to this:

for (auto i = entityTbl.begin(); i != entityTbl.end(); i++)
    for (auto k = entityTbl.begin(); i != entityTbl.end(); k++)

for more information: http://www.learncpp.com/cpp-tutorial/121-pointers-and-references-to-the-base-class-of-derived-objects/

http://www.cprogramming.com/tutorial/stl/iterators.html

Good luck.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top