Toromak
Toromak

Reputation: 29

C++: Having many objects

So, I have a question about C++. Let's say that I have an enemy class for a game. I want to be able to have (in theory) an infinite amount of enemies in my game. So I would have to have multiple instances of each class, and I would need to be able to access these separately. Would I have to have an array of enemy objects with an unlimited amount of space for the array, and I would use the new and delete operator to create and remove enemies in the array? Then I would need a variable to hold the number of enemies, right?

Upvotes: 2

Views: 1837

Answers (7)

UpAndAdam
UpAndAdam

Reputation: 5467

Would I have to have an array of enemy objects with an unlimited amount of space for the array

I would say that's most likely a bad idea. Depending on the design and nature of these 'enemies' you might not need to have ALL of the data for all of them in memory all of the time... What happens to your game when you run out of memory?

Does every enemy object really need to be full object? Take a look at the flyweight design pattern. I surmise you don't really need to have all of them at once.

The concept of an instance of enemy class literally corresponding to a single enemy might be where you are steering wrong.

Other potential patterns include proxy and prototype.

and I would use the new and delete operator to create and remove enemies in the array?

Depends upon your implementation. If you malloc/new you must free/delete. That's trivial and not related to the container you put the objects in, but instead dependent upon the creation process.

Remember if you are in a game and have to constantly call malloc/new for creation of your enemies your game's performance is going to suck. Everytime you'll be headed to system calls into OS which can only be granted to one thread at a time, if a bunch happen on different threads at once you'll get a lot of lag which may or may not matter to you; giving the context I'm going to assume this doesn't matter to you right now, but for the sake of others I've mentioned it anyways. I'd suggest figuring out how many you'll roughly need and obtain all the memory needed before hand, and if you ever run out, request twice as much.... but this is a whole seperate topic on memory management... which really has little to do with your data structure and construction paradigm.

Then I would need a variable to hold the number of enemies, right?

Depends how you are storing them. If you are using a c-array you are managing yourself yes. Most formal containers have fairly efficient methods to obtain their size. But there may be caveats in between.

However given you are asking this question I think you should really step back from the immediate implementation details and lines of code and look at the higher level architecture you are putting together which doesn't seem thought out or understand. "Begin with the end in mind"

It's not possible for anyone to definitively answer your question in its current form in a worthwhile manner. It seems like your real questions are:

  1. What are containers, and how do they work?
  2. What's an efficient paradigm to manage these large collections of enemies (seriously look up FlyWeight from the Gang of Four's Design Patterns)
  3. How should I go about constructing my datastructure?

Regarding 1: There are tons of questions/answers about data structure all over this site, and plenty of books and documents about the myriad of existing data structures. STL provides dozens, as does Boost. I'm not going to rehash that here.

Regarding 2. As I said you need to look at well known patterns to solve this problem. I gave some suggestions above. Without more inforamtion this is the most generically useful information I can provide that might be useful to someone else.

Regarding 3. I think you should probably consider a Factory method or abstract factory or something like that if you insist upon discrete items, so that you don't have to litter your code with handling of memory allocation failing and not being able to instantiate anymore enemies.

Upvotes: 1

Captain Skyhawk
Captain Skyhawk

Reputation: 3500

The answer to what kind of data structure has been answered:

std::vector

This hasn't been answered from a game programming perspective yet, so here it goes.

You'll run into problems fast if you're using a data structure like Vector without regards for how many objects you're storing.

Most game loops are going to update each of the "character" objects in your array. Chances are, if you're worrying about "infinite" characters, you will not want to update every character in the update function of your game.

If you're only going to have a few characters, or a manageable amount, a Vector will be fine.

However, if you're going to have a world with hundreds or thousands of characters. A Vector is no longer the data structure you will want to use.

In this case, you'll be much better suited with something called a quadtree(2d) or octree(3d). The explanation of these data structures is outside the scope of this answer. Just know they will be much more efficient for game purposes.

Upvotes: 3

Felix Glas
Felix Glas

Reputation: 15524

Use std::vector. It will automatically allocate more memory as needed.

There are also other containers in the standard library that will automatically allocate memory when needed like for example std::list, std::set or std::map. These containers may be more suitable in special cases, however std::vector is usually the best choice. It all depends on the implementation details.

You can use it like this:

#include <vector>

struct Enemy {
    //...
}

std::vector<Enemy> v;

Enemy e1, e2;
v.push_back(e1);
v.push_back(e2);

std::cout << "First enemy in vector: " << v[0];

Upvotes: 5

syam
syam

Reputation: 15069

That's why we have containers in C++: vector, list, deque, and many more specialized ones (eg. map, an associative container).

They are able to grow and shrink as needed, you can add and remove items easily. Which one you use depends on your exact needs (lookup complexity, random access, insertion complexity, ...).

As others have mentioned, a vector is probably a good place to start if you are not used to standard containers, and with time you will learn to choose the right container for the right job.

Upvotes: 1

Arun
Arun

Reputation: 20383

In C++, std::vector<> is a data structure for dynamically resizable arrays. I would start with a vector of enemies.

class Enemy { ... };

std::vector< Enemy > enemyCollection;

The vector data structure would take care of the memory management for you. See http://www.cplusplus.com/reference/vector/vector/ for reference.

Upvotes: 1

user1599559
user1599559

Reputation:

You probably want to use a container from the standard library. The best start will probably be a vector, from the standard library. It is like an array, but expands based on the number of items you add to it. That way you aren't wasting any space.

Depending on your specific requirements, there are other containers which have different performance characteristics. But a vector is usually a very good starting point. This is a very good reference for picking a standard container.

Upvotes: 1

Alex Chamberlain
Alex Chamberlain

Reputation: 4207

Just use a std::vector; it is a dynamic array with an infinite bound.

Upvotes: 0

Related Questions