Making a list of variables without copying them - c++

The Main question:
How do you create a pointer to a variable that can be stored and then used to access this variable at a later time Without a copy being created
The below is here just to answer any questions that people might have as to why I want to do this
Prologue:
I am making a game with DirectX and I want to create a "list" of Entities(A special class) in a another class. I want to do this so I can keep track of all the objects in the game that are rendered by a specific method(One list for triangles, another for lines, ect). To do this I originally just had a class and it had a std::vector<Entity>, the class then had an add(Entity entity) function which would add the specified entity to the vector. This worked out very well until I started trying to make changes to these entities in the vector.
The problem:
First I would create an entity in the main world loop, Entity testEntity = Entity(position); then I would add it to the entity list, entityList.add(testEntity);. When this command is called it is actually just making a copy of the entity as it is at the time that the add command was called. This means that there are suddenly 2 entities that represent 1, The entity in the main world that is being affected by all the game logic, and the entity in the entityList that does not update, but renders. These two are not in sync.
The desired effect:
The entityList's std::vector is actually just filled with some sort of pointer to the entities in the world loop. Then when an entity is updated in the world loop the entityList has the same data for that entity.

It's not entirely clear to me where you're having trouble, so this may not answer the question:
It seems like you want to just store a vector of pointers to Entity objects. I.e. std::vector<Entity*>.
If you know that testEntity will be in scope for the lifetime of the vector, you could just add a pointer to it to your vector. I.e. entityList.add(&testEntity).
If that assumption isn't true, you probably want to allocate your Entity objects on the heap (e.g. Entity* testEntityPtr = new Entity(position);. If you're using C++11 (or maybe even if you're not), you probably want to use shared_ptr and make_shared in this situation.

You could possibly use the c++ 11 Move Semantics to preserve your data. If Entity have pointer members that point to some allocated data that you do not want to copy you could implement Move semantics that would essentially transfer ownership the the copy that you are placing in the vector.
For example:
Entity(Entity&& entity)//move constructor
{
this->data = std::move(entity.data);
//and so on.
}
You will also need a "Move assignment operator" Entity& operator=(Entity&& entity);
You will need to look up "Move Semantics" and "rvalue references" for more info.
I hope this helps.

Related

Erase object in both base class vector and derived class vector

In the game I am designing, I have a derived class Bullet that inherits from the class Model. I have two vectors of shared_pointer for both of those classes. Every bullet is in the model's vector. Whenever a bullet reaches the end of its lifetime, it is then erased from the bullet's vector. Since that same object is in the model's vector, is there a quick way of erasing it as well? I can't use the index from the bullets vector because that index does not match its index in the model class. I tried creating a function that included delete this in the bullet class but that crashed the program and isn't recommended after some research. I thought about assigning each model an ID, getting the ID from the bullet before erasing it, and then erasing it in the model's vector based upon that ID. That to me doesn't sound like the best way of doing it. What are some alternate solutions?
Note: The vectors are defined as std::vector<std::shared_ptr<Model>> models. same goes for bullets
Edit: I first loop through the vector of bullets. If it is found that a bullet at the index is at the end of its lifespan, then the object at that index is erased (bullets.erase(index)). This can not be done in the models class, because the index is most likely different. I need the objects in both vectors to be erased for the actual object to go out of scope, and be destroyed, right? The reason there is a bullets vector and a models vector is that some operations should only be done on the bullets check lifespan for instance. Some operations should be done on all models including bullets, for instance, calculate velocity. I tried separating bullets from models, but that lead to redundant code that could have been achieved if all models were in one vector.
A solution to this would be to use some form of weak ownership. This is how entity component system usually work: You have a reference, call it a model or an entity doesn't matter. Make them all non-owner. If you insist on using std::shared_ptr, then you will have to use std::weak_ptr everywhere. Then, simply have one and only one place where you have all the std::shared_ptr. If you remove one of them, all the weak reference to it becomes invalid.
System that implements that won't usually use shared and weak pointer, but instead a pointer to the lifetime manager object (usually called entity manager or entity system) and also an identifier that is used to fetch the strong reference. That way, you keep having easy to use objects, and you get the benefit of having a single place to safely manage the lifetime of any game objects.

When would you use a vector of shared pointers and when would you use a vector of just plain objects?

I have a quick question.
I started learning C++ a while ago and have always used vectors with shared pointers of objects in them. Or at least smart pointers.
I'm currently programming a game and I was thinking about why I would use smart pointers.
Assume I have a Game class and it has a vector of players.
When would I want to choose for
vector<Player> players and when would i want to choose for vector<shared_ptr<Player>>?
Use shared_ptrs if the state of the entities is accessed other than in the vector. Also if you make an event-loop, with events like "player collided with other entity". You need to copy a pointer/reference, else you cannot change the state of the entities.
Another important thing is when the entity dies but an event with the entity is not handled, so the entity is deleted from the vector. When you use shared_ptr, the entity lives further, until the event in the eventqueue is deleted. When you store the whole player in the vector, the pointer stored in the event-object is not pointing to the correct entity anymore, if the vector changes its size. When you use a shared_ptr, the entity can be used normally, even if it is not existing in the vector anymore. But it is better to use std::weak_ptr in the event, that the entity is deleted, when it is dead, weak_ptr can check if the pointer is a dangling pointer which means the entity is dead and no event needs to be handled.
Using levels/dimensions, in which the vector of entities lives: When some entity goes to another level, the entity needs to be moved to that level, copying the whole struct is not the best idea. So the best idea is to use some pointer type like shared_ptr, but I recommend to std::move the shared_ptr to reduce reference counting overhead. With std::move the shared_ptr is as fast as a raw ptr.
Virtual classes of entities: When you are writing a game in a 2D or 3D world, you want to store many entities of different kind in the vector, you must use some pointertype to refer to the object, because the entities may have different size.
Fixed player count: If you are programming a game with fixed count of players like a card-game, you do not move the players nor you delete one (however you can just set a flag to indicate that the player is dead and you do not need to erase the entity from the vector), the best way is to use std::vector<Player>.
I think, using shared_ptr living in the vector and with weak_ptrs referencing in events is the best way to manage entities. While weak_ptr(the faster way) does not keep the memory of the Entity alive, the pointer needs to be checked every time.
Some pseudo code
if(fixed count of players
&& there are no other entities
&& there are no virtual subclasses of Player) {
class Player { ... };
using player_collection = std::vector<Player>;
using reference_to_player = Player*;
} else {
class Entity { public: ... virtual ~Entity(); };
class Player: public Entity { ... };
using entity_collection = std::vector<std::shared_ptr<Entity>>;
using reference_to_entity = std::weak_ptr<Entity>;
};

Automatically add an object to a vector of that objects parent

I am designing a game engine in c++. I am currently working on categorizing the different entities in the game. My base class is SpriteObject that two classes MovableObject and FixedObject inherit from. Now if i for example create an instance of a MovableObject and want to add it to a Vector of Sprite and a Vector of MovableObject i just do:
Vector<Sprite*> sprites;
Vector<MovableObject*> movableObjects;
MovableObject* movingObject = new MovableObject();
sprites.push_back(movingObject);
movableObjects.push_back(movingObject);
But as the different categories and entities grow the code will get large (and it would get tiresome to add every entity to every vector that it belongs to). How do i automatically add an object to the vector that it belongs to when it is created?
EDIT 1: I think i just came up with a solution, what if i just make a global static class Entities that holds all the vector of entities in the scene. Every entity could have access to this class and when a entity is created it just adds a pointer version of itself to the corresponding vector(s) in that global class.
EDIT 2: But i forgot that my solution requires me to still manually add every entity to its matching vector. I just split the work among the different entities.
This is a nice problem.
I think that I would implement it like this: There will be an addToVector() method in Sprite class, and each derived class will override it to add itself to the corresponding vector.
I would suggest a different approach. But before I start I would like to note one thing with your current design.
I would hide the creation of those objects behind a facade. Call it a scene or whatever. Using new manually is bad from a couple of perspectives. First of all if you decide you want to change the scheme on how you allocate/construct your objects you have to change it everywhere in the code. If you have a lets say a factory like Scene you just change the implementation and the calls to scene->CreateObject<Sprite>() will remain the same everywhere else. This might get important once you start adding stuff like custom memory allocation schemes, object pools etc and at some point you will if you will start to grow your engine. Even if this is just an excercise and a for fun project we all want to do this like its actually done, right ;) ?
Now going back to the core - dont abuse inheritance.
MovableObject is not a Sprite. Static Object is not a sprite either. They are that, movable and static elements.
A sprite can be movable or static, so it has a behavior of a dynamic or static element.
Use composition instead. Make a Sprite accepting behavior, or better a list of behaviors. In fact the Sprite itself is just a behavior on a Game object too, it just controls the way it is presented to the user.
What if you had an object that can be attached multiple behaviors like the fact it is a dynamic one, it has a sprite presence on the scene and even more is a sound emitter!
If you add those behaviors to the object you have to create them first. They can, when constructed, decide to which list they should subscribe to.
This is all metaphors for actually a well known system, that is proven to work well and is actually used in most game engines nowadays. Its a Entity Component System.
You object with behaviors are Entities, Components are those Behaviors and each of them is controlled by one system that knows the component and knows how to update/handle them.
Objects in the scene are merely a set of components attached to them that act upon them.

C++11 take ownership of unique_ptr by the raw pointer or reference?

Edit
I suppose the code below would assume I have an overloaded version of addChild() that accepts a Sprite already wrapped in a unique_ptr, where taking ownership would be fine. Just thought I'd mention that before someone else did. :) . I made up all the code here after a very long day, so please take it as pseudo code quality meant only to demonstrate the issue at hand.
Original Question
I'm writing a framework where there is a display list, parents/children etc. I'm thinking that using unique_ptr<Sprite> for example is the way to go here, since when you add a child to a parent display object, it's only logical that the parent now becomes the sole owner of that child.
However, there will be methods available such as getChildAt(index) and getChildByName, etc, which I believe should return a reference or pointer value, since these methods are simply meant to expose a child to operations, not transfer ownership.
Finally, the issue and the reason for this question, is in the following situation. Lets assume we have two Sprite objects which are children of the root of display list, Stage. Let's say we have a third child Sprite.
Stage newStage;
std::unique_ptr<Sprite> parentOne(new Sprite);
std::unique_ptr<Sprite> parentTwo(new Sprite);
newStage.addChild(parentOne); //Stage takes ownership of parentOne
newStage.addChild(parentTwo); //Stage takes ownership of parentTwo
std::unique_ptr<Sprite> someChild(new Sprite);
parentOne->addChild(someChild) //parentOne takes ownership of someChild.
Now, somewhere else lets say in the code base of the game or whatever using this framework, someChild is accessed via getChildAt(int index);.
Sprite& child = parentOne->getChildAt(0);
It would be perfectly legal for the following to then happen.
parentTwo->addChild(child);
The addChild method handles removing the child from it's previous parent, if a parent exists, so that the new parent can now make this child part of its section of the display list.
I'm returning the child(ren) from each sprite as a reference or pointer, because we don't want to hand off ownership (in methods such as getChildAt()), just provide access to the child. We don't want to hand it off as a unique_ptr and have it fall out of scope and die.
However, as I say, it would be perfectly legal and normal for this child (now accessed by a reference or pointer) to be passed off to another container (lets say in a drag and drop operation, dragging an item from one list to another). The problem we have now is that the unique ownership needs to be transferred from one parent to another, but we only have a reference or raw pointer.
I'm wondering what a sane solution to this problem would be. If I return a pointer, is it possible to transfer the ownership correctly at this stage?
void Sprite::addChild(Sprite* newChildToOwn)
{
/* by checking newChildToOwn->parent we can see that the child is already owned
by someone else. We need to not only remove the child from that parents' part of the
display list and add it here, but transfer exclusive object ownership of newChildToOwn
to this->.
*/
}
The release method gets you the pointer to the object and releases it from the unique_ptr
http://en.cppreference.com/w/cpp/memory/unique_ptr/release
For your structure, you should probably have method called releaseChild(index) that handles you the ownership by returning pointer.
To transfer ownership you need to have access to the unique_ptr as the raw pointer knows nothing of how it is being used.
Would it work to have the remove child method return the unique_ptr so that the object is kept alive during the transfer and the Sprite will be able to take the ownership? This will allow references to be used in other places as you have already.

Class Objects or Pointers to their Objects? Class object combination and Implementation

Background of the issue
I'm working on a basic battleship-like spinoff game that I want to continue to add features to over time in C++ (no graphics). Currently I have a 50 x 75 game board, represented with a 2D vector (called GameBoard) that is currently of type char. I create a game board and set each location with '.' char. As you guess coordinates, previously guessed locations are marked with '-' and hits are marked with 'X'
Where I'm at with the program
I decided to modify the game to enable some more features. I'm not too far along, but sketching up a design in pseudocode started making me think more about how I can go about this upgrade.
Instead of the GameBoard being chars, I'm creating a class called Block (an empty space on the board), which will now have a x and y coordinate variables, along with a char variable to visually display the correct char. Block has the ability to hold the object "Feature" which breaks off into derived classes of "feature." You can scroll to the very bottom for more detail about these classes.
This is how my class hierarchy tree goes:
feature
item vehicle
gold nuke plane
What I need help with
I basically have the outline/structure setup for what I want to do. Now I just need some help kickstarting it to get everything to connect. I'm pretty bad with determining when and how to use pointers.
A.) Should I change GameBoard to hold pointers of the Block class? Or actual Block objects?
- And would Block hold a pointer to a Feature or the actual Feature object?
B.) How do I add a Feature variable that can be empty or given a value? Do I just set it to NULL?
C.) Do I need a custom copy constructor to swap the Feature value of Block?
D.) How do I go about removing the Feature object from Block if the player uses it?
E.) Can there be more than 1 Feature on a single Block occasionally?
F.) How do I declare the Block and Feature classes such that Block can hold a Feature and Feature is already derived from another class (not included in this post).
Extra Details about my classes
So GameBoard is the vector that will store Blocks. Blocks are essentially the individual spaces on the board. Block contains coordinates for its location, a char to represent it, and the possibility to hold a Feature object, but most of the time the Block won't be holding a feature. Feature is derived from Block and acts as a bonus reward in the game. So Feature branches into 2 more derived classes, an Item Feature or Vehicle. And so on.
When the player chooses coordinates, a method will go to that Block on/in the GameBoard and first check if the char value represents a valid space that hasn't been used before. Then it checks the contents of this Block for Feature. Feature may be empty or contain a derived Feature object.
Ok that concludes my novel. Sorry for writing so much. I figure the best way to get help is to let the helpers know what's going on. PLEASE don't respond telling me to "get to the point." I know I know.. Let me know if I'm missing details. Thanks!
I am assuming you want to keep your class structure. At your point of abstraction I am suggesting using shared and uniqe pointer via (C++11 or Boost). If you're pretty bad at pointers learn how uniqe and shared pointer work and try to stick with those. Remember to keep the object's life scope as short as possible.
A.) Should I change GameBoard to hold pointers of the Block class? Or actual Block objects? And would Block hold a pointer to a Feature or the actual Feature object?
I want keep this GameBoard elements as immutable uniqe pointers or keep actual instances.
B.) How do I add a Feature variable that can be empty or given a value? Do I just set it to NULL?
You have decided to keep Feature inside Block - ok. If so keep it as shared pointer. If there is no feature shared pointer will be empty.
C.) Do I need a custom copy constructor to swap the Feature value of Block?
Only if there is something dynamic/unusual inside Feature. What will the Feature hold?
D.) How do I go about removing the Feature object from Block if the player uses it?
If you use shared pointer there's no problem. Even if the Feature have changed during handling previous Feature, Feature will be handle correctly and destroyed when it's no longer required by GameBoard.
E.) Can there be more than 1 Feature on a single Block occasionally?
You have to ask yourself this question - does your game require handling this situation? If so simply hold vector/map/set/array (depending on your requirements) of shared pointers to Features.
F.) How do I declare the Block and Feature classes such that Block can hold a Feature and Feature is already derived from another class (not included in this post).
I am not sure if I understand the question correctly:
class Feature : public GameElement {
/* Feature implementation */
}
class Block {
shared_ptr<Feature> mFeature;
/* Block implementation */
};
Does it answer your question ?
I am not sure if it is a good idea to derive class feature from class block
I would rather use a pointer to feature within each instance of block, this way the pointer is NULL if there is no feature. This pointer would be pointer to the base class feature in your case. I encourage use of virtual methods to access individual features.
when a feature is used up, delete it and set pointer to it to NULL. (the pointer that is within the block instance)
if you want to have more than one feature per block at a time, consider using some kind of array/stack of pointers.
in my opinion the GameBoard should hold actual instances (not pointers) of Blocks.
I do not understand what do you mean by:
Do I need a custom copy constructor to swap the Feature value of Block?
I hope this helps =).
I think it would be a good idea of your GameBoard is a container for GameObject pointers. You don't need to create a whole new class and call it Block - all this is implied. There is also no need to track the coordinates of blocks, since they are arranged in order. A GameObject would be the base class for the hierarchy of game elements - in your case that would be a Feature, the reason I used GameObject is because Feature is just not very descriptive - the term is too broad with wide scope.
When the game is started, your GameBoard can be populated by null pointers which are subsequently substituted by the actual game elements that are created and added to the board.
You only need to implement copy constructor and assignment operator if you have dynamically allocated data. If not, the compiler will generate a perfectly good version that will do raw object copy.
That being said, you'd better not move actual object instances around, and with the proposed method of using pointers instead, you will only be moving pointers, which is much simpler and faster.
If you want to remove a Feature, just delete the actual object and set its pointer in the board to null.
If you implement a parent/child relation you can have a tree of GameObjects in each block, and you can traverse that tree recursively and do to the tree elements as you will.
A well designed polymorphic hierarchy will allow you to put pretty much anything as long as it is derived from your base class.