I use global maps to register one or several objects of the same type. I started with using a global namespace for that purpose.
Take this for an example (code untested, just an example):
//frame.h
class frame
{
public:
frame(int id);
~frame();
};
namespace frame_globals
{
extern std::map<int, frame *> global_frameMap;
};
//frame.cpp
#include "frame.h"
namespace frame_globals
{
std::map<int, frame *> global_frameMap;
}
frame::frame(int id)
{
//[...]
//assuming this class is exclusively used with "new"!
frame_globals::global_frameMap[id] = this;
}
frame::~frame()
{
frame_globals::global_frameMap.erase(id);
}
This was a rather quick solution I used, but now I stumble again on the use case, where I need my objects registered and I asked myself if there was no better way, than using a global variable (I would like to get rid of that).
[EDIT: Seems to be incorrect]
A static member variable is (to my best knowledge) no option, because a static is inline in every object and I need it across all objects.
What is the best way to do this? Using a common parent comes to mind, but I want easy access to my frame class. How would you solve it?
Or do you know of a better way to register an object, so that I can get a pointer to it from somewhere else? So I might not exlusively need "new" and save "this"?
I would consider reversing the design. eg. what is wrong with using language built functionality ?
std::map<int, frame> frames_;
frames_.emplace(id);//adding, ie. creating frames
frames_.erase(id)//removing, ie. deleting frames
Now creating/deleting is as easy as before. Coincidently, if someone needs a frame for a different purpose there is no issue here. If frame is supposed to be polymorphic you could store std::unique_ptr instead.
Also I would consider making id a member of frame and then store in a std::set instead of std::map.
class frame
{
public:
int id;
frame(int id);
friend bool operator <(const frame& lhs, const frame& rhs) {return lhs.id < rhs.id;}
};
std::set<frame> frames_;
Deleting is just:
frames_.erase(frame);
However in order to lookup based on id is now somewhat more complicated. Fortunately theres a solution at hand. That requires implementing a compare that is transparent, which among other things involves defining is_transparent.
Overall you need to think about ownership. Ask yourself: where or who would own/store the map/frame pointers/etc. Store it there. In case of shared ownership, use a shared_ptr (but use only this pattern when actually needed - which is more rare than what people use it for).
Some relevant core-guidelines
I.3 Avoid singletons
R.5 and R.6 Avoid non-const global variables
R.11 Avoid calling new and delete explicitly
R.20 and R.21 Prefer unique_ptr over shared_ptr unless you need to share ownership
You should ideally have a factory pattern to create a delete frame objects. The constructor of the frame must not be managing the map. It's like citizens are manging their passports (ideally govt does that for citizens). Have a manager class to keep frame in map (std::map<int,frame>). A method provided by the manager class would create the object:
class FrameManager
{
std::map<int,frame> Frames;
public:
frame CreateFrame(int id)
{
frame new_frame(id);
Frames[id] = new_frame;
}
};
What about removals? Well, depending on your design and requirement, you can have either/both of:
Removal of frames by the destructor of the frame. It may call FrameManager::Remove(id);
Allow removal also by FrameManager only (FrameManager::Remove(id)). I'd choose this (see more below).
Now, note that with this approach, many objects so frame will get created (local, assignment to map, return etc.). You may use shared_ptr<frame> as the return type from
CreateFrame, and keep shared_ptr as the type of map map<int, shared_ptr<frame>>.
It may seem complicated to use shared/unique_ptr but they become really helpful. You don't need to manage the lifetime. You may pass same shared_ptr<frame> to multiple functions, without creating frame object multiple times.
Modified version:
class FrameManager
{
std::map<int, shared_ptr<frame>> Frames;
public:
shared_ptr<frame> CreateFrame(int id)
{
if(Frames.count(id)>0) return nullptr; // Caller can check shared_ptr state
shared_ptr<frame> new_frame = make_shared<frame>(id);
Frames[id] = new_frame;
return new_frame;
}
};
Using a frame-manager will allow complete control over frames creation, better error handling, safe/secure code, safe multithreaded code.
I would like to put few points base on code posted by you.
How some one will know about frame_globals::global_frameMap and what it does with out looking source code.
If it is a global object then frame class logic can be bypassed and global object can be modified from outside.
What if someone wants to mange frame objects in different way or if in future some requirement changes for example if you want to allow duplicate frames then you have to change frame object.
frame class is not only having frame related data member and member function but also have managing logic. It seems not following single responsibility principle.
What about copy/move constructor? std::map/std::set will affect constructors of frame class.
I think logic separation is required between frame and how to manage frames.I have following solution ( I am not aware of all use cases, my solution is based on posted code)
frame class
frame class should not have any logic which is not related to frame.
If frame object need to know about other frame objects then a reference of ContainerWrapper should be provided (not directly std::map or std::set, so that change will not impact frame)
ContainerWrapper class
ContainerWrapper should manage all the frame objects.
It can have interface as per the requirement, for example try_emplace which returns iterator of inserted element (similar to std::map::try_emplace), so rather then first creating frame object and then try to insert in std::map, it can check the existence of the id(key) and only create frame object if std::map doesn't have any object with specified id.
About std::map/std::set,
std::set can be used if frame object once created is not required to modify because std::set will not let you modify frame without taking it out and re-inserting it or you have to use smart pointer.
By this way a container object can be shared across multiple frame objects and doesn't have to be global object.
Related
I recently found out for the past few years of me using C++, I have been using pointers far too often and usually when I could easily substitute them for something more appropriate. Something I used them for was using one to allow an object to be uninitialized, and easily check so.
For example, let's say I have a camera that I want to be attaching to an object in a game:
Class Camera {
public:
Entity *attachEntity;
Camera() {
attachEntity = nullptr;
}
void update() {
// If there's an entity to be attached to
if (attachEntity != nullptr) {
...
}
}
};
Is this a bad usage of a pointer? I can't find a good way of doing this without using one. And if it's not supposed to be attached to the entity, you can just set it to nullptr again if it's a pointer. Otherwise, there needs to always be an attachEntity, despite whether or not the camera is attached to it at the moment. Is there anything wrong with this practice? Is there a good way to do this without pointers? I saw that you can't just set an object to NULL like you can a pointer. What's the best way of doing this?
If you want value semantics but still need to be able to omit a
value, you can use std::optional.
You get similar behavior with a std::unique_ptr, except that
the Entity takes up no space when absent but otherwise goes into its
own block of dynamically-allocated memory.
If you want non-owning reference to an Entity instance whose
lifespan will exceed that of the Cameria instance, a raw pointer is
appropriate.
When the Entity is potentially used by multiple Cameras (or other
things) and you need to ensure its lifespan is extended until its
last use, that's where std::shared_ptr fits in.
As Michael pointed out, there's also std::weak_ptr, which is
good to know about but typically rare in practice. It's used to
address a shared_ptr without keeping it alive.
(edited to add #5)
Yes.
Use std::shared_ptr which auto-destructs when no longer needed.
And then you forget everything about copy/move constructors in your classes.
Also it initializes itself to nullptr automatically; No need for your constructor then.
You can also use std::unique_ptr if you are sure that your pointer isn't going to be duplicated, for example, when you only have one object of type Camera. Usually I use shared_ptr to allow copies over threads etc.
Class Camera {
public:
shared_ptr<Entity> attachEntity;
void update() {
// If there's an entity to be attached to
if (attachEntity) {
...
}
}
};
Generally, raw pointers are only nowadays useful to call pointer-only functions, like WinAPI etc. That way, your classes won't need copy/move constructors or assignment operators or destructors, unless you want to move/dup an object which is not visible to the language, like a HANDLE in Windows.
Since you want to attach the camera to one specific entity and change the attachment, you need a pointer.
Since the existence of that entity should be independent of the camera, a raw pointer is appropriate.
If all your entities are shared (as shared_ptrs), a weak_ptr would be best, but it’s not obvious that they should be.
Your solution for the camera is perfectly valid. All the other answers take a long way around of telling you you're doing the right thing by pointing you to shared pointers and optional types, but storing the attach entity as a pointer and using it the way you are is exactly how you would expect it to be done.
I'm going to have some haters, but I personally HIGHLY encourage the use of raw pointers (instead of smart/shared pointers) for real-time applications :).
I am in a bit of a pickle. I am using the boost::serialization in order to save/load a pointer from memory. The saving part, I have no issues. I was able to verify that the serialization class is able to save the pointer without any issue. As a side note, the pointer class is a custom class that I created.
Some background. I am using the wxwidgets library to create a GUI. I am using the latest version (v3.1.0). The object inherits from the wxGLCanvas class. Which requires a pointer to the parent window. The class is being used to draw a grid on the screen and the user can interact with the grid by placing geometry shapes (mainly squares, arcs, and lines). Each shape is its own class. Within my class, I have datatypes that specify the grid step size, the placement of the camera, the zoom level, and the geometry shape vectors. All of these are able to be saved. Note that my class does specify other data types as well but I am not saving these so they are irrelevant to the discussion. As a side note, the class in question is called modelDefinition
Now, we come to the load part of the class. My current implementation is as such:
void MainFrame::load(string filePath)
{
std::ifstream loadFile(filePath);
if(loadFile.is_open())
{
modelDefinition temp(this, wxPoint(6, 6), this->GetClientSize(), _problemDefinition, this->GetStatusBar());
//modelDefinition tempDefintion = (*_model);
boost::archive::text_iarchive ia(loadFile);
ia >> _problemDefinition;
ia >> temp;
temp.copyModel(*_model);
//*_model = temp;
//(*_model) = tempDefintion;
_model->Refresh();
}
}
Implementation of the copy function:
void copyModel(modelDefinition &target)
{
target.setGridPreferences(_preferences);
target.setEditor(_editor);
target.setZoomX(_zoomX);
target.setZoomY(_zoomY);
target.setCameraX(_cameraX);
target.setCameraY(_cameraY);
}
My idea is this, that I create a temporary variable and initialize it to the values that I need it to be. Currently, it is empty. Then, I will load the data into the temporary variable and then copy the needed data structures into my main variable. However, the program crashes at ia >> temp. I am not sure why right now. I go into the debugger and I do not get access to the call stack after the crash. I have a feeling that it is crashing within the boost library. I did place a break point within the serialize function in modelDefinition and the program never made it.
I did come across this forum posting:
Boost serialization with pointers and non-default constructor
To be honest, I am not too sure if it applies to me. I am trying to think of a way that does but so far I can not find any reason that applies to me.
Here is the declaraction of the modelDefinition constructor:
modelDefinition::modelDefinition(wxWindow *par, const wxPoint &point, const wxSize &size, problemDefinition &definition, wxStatusBarBase *statusBar) : wxGLCanvas(par, wxID_ANY, NULL, point, size, wxBORDER_DOUBLE | wxBORDER_RAISED)
par MUST have a value. Null values are not accepted. I did see that the forum post did override the load function and grabbed the values and passed them into the constructor of the class. However, in my case, par is a this pointer and I am not able to serialize the function and load this back into the program (besides, this will change on every single function call). this refers back to the parent window. And overriding the load function in a different namespace prevent me from passing this into the function. So basically, that option is out of the water (unless I am missing something).
Again, since I can't pass in NULL into the wxGLCanvas constructor, this option is off the table:
modelDefinition _model = new modelDefinition();
modelDefinition::modelDefinition() : wxGLCanvas(NULL, 0)
And I believe that this option is also off the table since my parent window that would be associated with the canvas is in a different namespace:
template<class Archive>
inline void load_construct_data(
Archive & ar, modelDefintion * foo, const unsigned int file_version
){
double test;// There would be more after this but to simplify the posting, I am just throwing this in here.
ar >> test;
::new(modelDefintion)_model(this, test); // Yeah, I don't think that this is going to work here.
}
Again, this would need to be pointing to the parent window, which I don't think that I have access to.
So right now, I am a little lost on my options. So far, I am thinking that I will continue to be working on the first case to see where the program is crashing.
Although, I could really use someone's help in solving this issue. How can I load back the data structure of a non-default constructor pointer where I cannot save the data from the inherited object (because modelDefinition inherits from wxGLCanvas data type and I am unable to save this data type)?
Yes, I am aware of the minimal example. It will take me sometime to create a minimal example. If the forum people need it to effectively come up with a solution, then I will do it and post here. But again, it will take time and could be rather long.
Yes, load/save construct data is the tool to deal with non-default constructibles.
Your problem is different: you need state from outside because you are trying to load objects that require the state during construction, but it never got saved in the first place. Had it been, you could re-create the parent window just like it existed during serialization.
The only "workaround" I can see here is to use global state (i.e. access it through (thread) global variables).
I do not recommend it, but you're in a pickle so it's good to think about workarounds, even bad ones
As soon as you salvaged your data from the old-style archives, I suggest serializing into a format that
saves all required construct data
serializes a data struct not tied to the GUI elements
Of course I don't know about the over-arching goal here, so I can't say which approach is more apt, but without context I'd always strife for separation of concerns, i.e. de-coupling the serialization from any UI elements.
I've been working with pointers for a few years now, but I only very recently decided to transition over to C++11's smart pointers (namely unique, shared, and weak). I've done a fair bit of research on them and these are the conclusions that I've drawn:
Unique pointers are great. They manage their own memory and are as lightweight as raw pointers. Prefer unique_ptr over raw pointers as much as possible.
Shared pointers are complicated. They have significant overhead due to reference counting. Pass them by const reference or regret the error of your ways. They're not evil, but should be used sparingly.
Shared pointers should own objects; use weak pointers when ownership is not required. Locking a weak_ptr has equivalent overhead to the shared_ptr copy constructor.
Continue to ignore the existence of auto_ptr, which is now deprecated anyhow.
So with these tenets in mind, I set off to revise my code base to utilize our new shiny smart pointers, fully intending to clear to board of as many raw pointers as possible. I've become confused, however, as to how best take advantage of the C++11 smart pointers.
Let's assume, for instance, that we were designing a simple game. We decide that it is optimal to load a fictional Texture data type into a TextureManager class. These textures are complex and so it is not feasible to pass them around by value. Moreover, let us assume that game objects need specific textures depending on their object type (i.e. car, boat, etc).
Prior, I would have loaded the textures into a vector (or other container like unordered_map) and stored pointers to these textures within each respective game object, such that they could refer to them when they needed to be rendered. Let's assume the textures are guaranteed to outlive their pointers.
My question, then, is how to best utilize smart pointers in this situation. I see few options:
Store the textures directly in a container, then construct a unique_ptr in each game object.
class TextureManager {
public:
const Texture& texture(const std::string& key) const
{ return textures_.at(key); }
private:
std::unordered_map<std::string, Texture> textures_;
};
class GameObject {
public:
void set_texture(const Texture& texture)
{ texture_ = std::unique_ptr<Texture>(new Texture(texture)); }
private:
std::unique_ptr<Texture> texture_;
};
My understanding of this, however, is that a new texture would be copy-constructed from the passed reference, which would then be owned by the unique_ptr. This strikes me as highly undesirable, since I would have as many copies of the texture as game objects that use it -- defeating the point of pointers (no pun intended).
Store not the textures directly, but their shared pointers in a container. Use make_shared to initialize the shared pointers. Construct weak pointers in the game objects.
class TextureManager {
public:
const std::shared_ptr<Texture>& texture(const std::string& key) const
{ return textures_.at(key); }
private:
std::unordered_map<std::string, std::shared_ptr<Texture>> textures_;
};
class GameObject {
public:
void set_texture(const std::shared_ptr<Texture>& texture)
{ texture_ = texture; }
private:
std::weak_ptr<Texture> texture_;
};
Unlike the unique_ptr case, I won't have to copy-construct the textures themselves, but rendering the game objects is expensive since I would have to lock the weak_ptr each time (as complex as copy-constructing a new shared_ptr).
So to summarize, my understanding is such: if I were to use unique pointers, I would have to copy-construct the textures; alternatively, if I were to use shared and weak pointers, I would have to essentially copy-construct the shared pointers each time a game object is to be drawn.
I understand that smart pointers are inherently going to be more complex than raw pointers and so I'm bound to have to take a loss somewhere, but both of these costs seem higher than perhaps they should be.
Could anybody point me in the correct direction?
Sorry for the long read, and thanks for your time!
Even in C++11, raw pointers are still perfectly valid as non-owning references to objects. In your case, you're saying "Let's assume the textures are guaranteed to outlive their pointers." Which means you're perfectly safe to use raw pointers to the textures in the game objects. Inside the texture manager, store the textures either automatically (in a container which guarantees constant location in memory), or in a container of unique_ptrs.
If the outlive-the-pointer guarantee was not valid, it would make sense to store the textures in shared_ptr in the manager and use either shared_ptrs or weak_ptrs in the game objects, depending on the ownership semantics of the game objects with regards to the textures. You could even reverse that - store shared_ptrs in the objects and weak_ptrs in the manager. That way, the manager would serve as a cache - if a texture is requested and its weak_ptr is still valid, it will give out a copy of it. Otherwise, it will load the texture, give out a shared_ptr and keep a weak_ptr.
To summarize your use case:
*) Objects are guaranteed to outlive their users
*) Objects, once created, are not modified (I think this is implied by your code)
*) Objects are reference-able by name and guaranteed to exist for any name your app will ask for (I'm extrapolating -- I'll deal below with what to do if this is not true.)
This is a delightful use case. You can use value semantics for textures throughout your application! This has the advantages of great performance and being easy to reason about.
One way to do this is have your TextureManager return a Texture const*. Consider:
using TextureRef = Texture const*;
...
TextureRef TextureManager::texture(const std::string& key) const;
Because the underling Texture object has the lifetime of your application, is never modified, and always exists (your pointer is never nullptr) you can just treat your TextureRef as simple value. You can pass them, return them, compare them, and make containers of them. They are very easy to reason about and very efficient to work on.
The annoyance here is that you have value semantics (which is good), but pointer syntax (which can be confusing for a type with value semantics). In other words, to access a member of your Texture class you need to do something like this:
TextureRef t{texture_manager.texture("grass")};
// You can treat t as a value. You can pass it, return it, compare it,
// or put it in a container.
// But you use it like a pointer.
double aspect_ratio{t->get_aspect_ratio()};
One way to deal with this is to use something like the pimpl idiom and create a class that is nothing more than a wrapper to a pointer to a texture implementation. This is a bit more work because you'll end up creating an API (member functions) for your texture wrapper class that forward to your implementation class's API. But the advantage is that you have a texture class with both value semantics and value syntax.
struct Texture
{
Texture(std::string const& texture_name):
pimpl_{texture_manager.texture(texture_name)}
{
// Either
assert(pimpl_);
// or
if (not pimpl_) {throw /*an appropriate exception */;}
// or do nothing if TextureManager::texture() throws when name not found.
}
...
double get_aspect_ratio() const {return pimpl_->get_aspect_ratio();}
...
private:
TextureImpl const* pimpl_; // invariant: != nullptr
};
...
Texture t{"grass"};
// t has both value semantics and value syntax.
// Treat it just like int (if int had member functions)
// or like std::string (except lighter weight for copying).
double aspect_ratio{t.get_aspect_ratio()};
I've assumed that in the context of your game, you'll never ask for a texture that isn't guaranteed to exist. If that is the case, then you can just assert that the name exists. But if that isn't the case, then you need to decide how to handle that situation. My recommendation would be to make it an invariant of your wrapper class that the pointer can't be nullptr. This means that you throw from the constructor if the texture doesn't exist. That means you handle the problem when you try to create the Texture, rather than to have to check for a null pointer every single time you call a member of your wrapper class.
In answer to your original question, smart pointers are valuable to lifetime management and aren't particularly useful if all you need is to pass around references to object whose lifetime is guaranteed to outlast the pointer.
You could have a std::map of std::unique_ptrs where the textures are stored. You could then write a get method that returns a reference to a texture by name. That way if each model knows the name of its texture(which it should) you can simple pass the name into the get method and retrieve a reference from the map.
class TextureManager
{
public:
Texture& get_texture(const std::string& key) const
{ return *textures_.at(key); }
private:
std::unordered_map<std::string, std::unique_ptr<Texture>> textures_;
};
You could then just use a Texture in the game object class as opposed to a Texture*, weak_ptr etc.
This way texture manager can act like a cache, the get method can be re-written to search for the texture and if found return it from the map, else load it first, move it to the map and then return a ref to it
Before I get going, as I accidentally a novel...
TL;DR Use shared pointers for figuring out responsibility issues, but be very cautious of cyclical relationships. If I were you, I would use a table of shared pointers to store your assets, and everything that needs those shared pointers should also use a shared pointer. This eliminates the overhead of weak pointers for reading (as that overhead in game is like creating a new smart pointer 60 times a second per object). It's also the approach my team and I took, and it was super effective. You also say your textures are guaranteed to outlive the objects, so your objects cannot delete the textures if they use shared pointers.
If I could throw my 2 cents in, I'd like to tell you about an almost identical foray I took with smart pointers in my own video game; both the good and the bad.
This game's code takes an almost identical approach to your solution #2: A table filled with smart-pointers to bitmaps.
We had some differences though; we had decided to split our table of bitmaps into 2 pieces: one for "urgent" bitmaps, and one for "facile" bitmaps. Urgent bitmaps are bitmaps that are constantly loaded into memory, and would be used in the middle of battle, where we needed the animation NOW and didn't want to go to the hard disk, which had a very noticeable stutter. The facile table was a table of strings of file paths to the bitmaps on the hdd. These would be large bitmaps loaded at the beginning of a relatively long section of
gameplay; like your character's walking animation, or the background image.
Using raw pointers here has some problems, specifically ownership. See, our assets table had a Bitmap *find_image(string image_name) function. This function would first search the urgent table for the entry matching image_name. If found, great! Return a bitmap pointer. If not found, search the facile table. If we find a path matching your image name, create the bitmap, then return that pointer.
The class to use this the most was definitely our Animation class. Here's the ownership problem: when should an animation delete its bitmap? If it came from the facile table then there's no problem; that bitmap was created specifically for you. It's your duty to delete it!
However, if your bitmap came from the urgent table, you could not delete it, as doing so would prevent others from using it, and your program goes down like E.T. the game, and your sales follow suit.
Without smart pointers, the only solution here is to have the Animation class clone its bitmaps no matter what. This allows for safe deletion, but kills the speed of the program. Weren't these image supposed to be time sensitive?
However, if the assets class were to return a shared_ptr<Bitmap>, then you have nothing to worry about. Our assets table was static you see, so those pointers were lasting until the end of the program no matter what. We changed our function to be shared_ptr<Bitmap> find_image (string image_name), and never had to clone a bitmap again. If the bitmap came from the facile table, then that smart pointer was the only one of its kind, and was deleted with the animation. If it was an urgent bitmap, then the table still held a reference upon Animation destruction, and the data was preserved.
That's the happy part, here's the ugly part.
I've found shared and unique pointers to be great, but they definitely have their caveats. The largest one for me is not having explicit control over when your data gets deleted. Shared pointers saved our asset lookup, but killed the rest of the game on implementation.
See, we had a memory leak, and thought "we should use smart pointers everywhere!". Huge mistake.
Our game had GameObjects, which were controlled by an Environment. Each environment had a vector of GameObject *'s, and each object had a pointer to its environment.
You should see where I'm going with this.
Objects had methods to "eject" themselves from their environment. This would be in case they needed to move to a new area, or maybe teleport, or phase through other objects.
If the environment was the only reference holder to the object, then your object couldn't leave the environment without getting deleted. This happens commonly when creating projectiles, especially teleporting projectiles.
Objects also were deleting their environment, at least if they were the last ones to leave it. The environment for most game states was a concrete object as well. WE WERE CALLING DELETE ON THE STACK! Yeah we were amateurs, sue us.
In my experience, use unique_pointers when you're too lazy to call delete and only one thing will ever own your object, use shared_pointers when you want multiple objects to point to one thing, but can't decide who has to delete it, and be very wary of cyclical relationships with shared_pointers.
I am currently working on a game where I have a couple of classes which each handles their own gameobjects. For these classes to actually represent something in the game they need to use another class which is the animation_manager.
The animation_manager handles the loading, drawing and moving of objects on the screen and is created at startup.
What would be the smartest way of passing the manager to the classes which handles the gameobjects?
Should it be done by a public pointer, by assigning it to a static pointer in the object class which every gameobject inherits from or should I simply just pass it as a pointer to the gameobjects/objects class constructor?
I am using C++03 so no new fancy fixes :P
EDIT 1:
There has been a lot of good suggestions and I am thankful for that.
Now I will not use weak pointers since I dont need the object handlers to take care of the deletion of the pointer as its going to exist from the beginning to the end of the program.
Singletons wont fit my needs either as I dont want any class to have access to it.
One thing that came to mind when reading the replies is: Would it be a good idea to make a static reference for the anim_handler in the Object class which all the handling classes inherits from?
I'd prefer the passing by constructor.
This way you can establish an invariant (i.e. the manager is always present) whereas later setting a field does not ensure it's always done.
Like thomas just posted you should use a shared_ptr or something similar (if not using C++11).
I try not to use static fields (except for constants) since it prevents you to use different manager objects for each gameobject. (Think of a debugging/logging manager class, or another wrapped manager).
You can keep this shared manager object in a shared pointer which is added to C++11 (or you can use Boost library) standard as shared_ptr.
It has a reference counting mechanism such that you do not have to worry about the ownership and memory management of related object.
Every gameobject can keep a shared pointer member to your animation_manager.
If your animator_manager is a unique object, another approach could be defining it as a signleton, eventually removing the need for storing any reference to it in the gameobjects handling classes and using some sort of static method like animation_manager::getInstance() to use it.
The performance impact could be easily minimized by reducing the calls to the getInstance() method, but it really depends on your design, can't be sure it would fit.
you should give it as a reference (if possible a reference to a const), not a pointer. Only if you would have a class hierarchy of animation managers a pointer (if possible const to a const) would make sense. In the latter case, you should consider using boost's shared_ptr. If move to C++11 later, the changes to C++11's shared_ptr are minimal.
From the design point of view, you might also think about using an observer pattern, so the animation manager can decide on its own when it is the right time to render without having too much boilerplate code.
Passing a reference would be the most favorable way when thinking as a good software architect, because it will allow easier testing and mocking.
However, a game(engine) is - in my opinion - such a special case of software where "good patterns" can be counterproductive sometimes. You will nearly always end up in the situation that you need some manager classes everywhere.
You might want to look at the god-object anti-pattern, to make all common managers available globally. I use one(!) globally accessible instance of an "Application"-instance, which contains some bootstrapping code and references to the most common manager classes, like this:
// application.h
class CApplication {
void init(int argc, char **argv); // init managers & co here
void shutdown();
void run();
CMemoryManager * memory;
CSystemManager * system;
CAudioManager * sound;
CInputManager * input;
};
// globals.h
CApplication * app;
// main.c
#include "globals.h"
int main(int argc, char ** argv) {
app = new CApplication();
app->init(argc, argv);
app->run();
app->shutdown();
return 0;
}
// some_other_file.cpp
#include "globals.h"
void doSomething() {
// ...
app->input->keyDown(...);
// ...
}
Bad style? Probably. Does it work? For me it does. Feedback is also welcome as comment!
I'm adding another answer because it's quite a different approach, when compared with the previuos one.
First of all I should clarify that I'm not experienced in game programming! :)
Anyway, as I was suggesting in my previous comments, maybe, I would take a different route. Immagine that you have a "game field" with walls and other static elemnts, and a number of "actors", like monsters, the player alter ego and so on...
I would probably write an ancestor "Actor", subcalssing "Player" and "Enemy" classes, then subclassing "Enemy" into "Dragon", "Zombie", "Crocodile" and so on. Maybe Actor could have a bounch of common attributes, like "location", "speed", "strenght", "energy", "direction", "destination" and a status, say "moving", "sleeping", "eating the player", "being eated"...
A typical game iteration, could be something like:
1) get input from the player
2) call a method of the player actor object, something like:
player->move(east, fast);
3) cycle trough a list of actors to update their status, say:
for (int i(0); i < enemies.size(); i++) {
// Checks the player position in the gamefield and setup a strategy to eat him
enemies[i]->updateStatus(player, gamingField);
}
4) cycle trough the list of actors and move them:
animator->animate(player);
for (int i(0); i < enemies.size(); i++) {
animator->animate(enemies[i]);
}
5) check if something interesting has happened (the player has been eaten by the crocodile)
I mean: this is a totally different approach, but I think that isolating the actors logic could be a good idea, and you could avoid the original problem completely.
It seems to me that there are no explicit answer for this question, but rather multiple ways of doing it which each has their own opinion on.
In case anyone else have the same question I am going to list them below:
Shared_Pointer:
This method will keep track of the amount of used pointers pointing to the address and if that count hits zero, then it will deallocate the memory. Is available in C++11 and the boost library.
A shared pointer can be passed to other objects the same way as a normal pointer.
Suggested by ogni42
Passed by constructor:
A pointer or reference can be passed to the object when it is being constructed. The upside of using a reference is that the programmer can't accidentally use delete on the pointer.
Prefered by Onur.
Use of singletons
Singletons are an unique extern class which holds a pointer to the object which can be accessed through a function.
This was suggested by Albert
Global variables
Simply a globally declared variables. Personally I do not recommend these as they can become a mess as they become available even from code which you wont need them in.
Suggested by Sir PanCake
static variables
This is what I ended up using. I made it so that only objects which inherited from my Object class could access the anim_handler. The way I did this was by declaring Object a friend of my anim_handler and then I made the static variable to retrieve the handler protected
Anyways, thanks for the support everyone! I appreciates it a lot and I even learned something new! :)
I've been thinking about the possible use of delete this in c++, and I've seen one use.
Because you can say delete this only when an object is on heap, I can make the destructor private and stop objects from being created on stack altogether. In the end I can just delete the object on heap by saying delete this in a random public member function that acts as a destructor. My questions:
1) Why would I want to force the object to be made on the heap instead of on the stack?
2) Is there another use of delete this apart from this? (supposing that this is a legitimate use of it :) )
Any scheme that uses delete this is somewhat dangerous, since whoever called the function that does that is left with a dangling pointer. (Of course, that's also the case when you delete an object normally, but in that case, it's clear that the object has been deleted). Nevertheless, there are somewhat legitimate cases for wanting an object to manage its own lifetime.
It could be used to implement a nasty, intrusive reference-counting scheme. You would have functions to "acquire" a reference to the object, preventing it from being deleted, and then "release" it once you've finished, deleting it if noone else has acquired it, along the lines of:
class Nasty {
public:
Nasty() : references(1) {}
void acquire() {
++references;
}
void release() {
if (--references == 0) {
delete this;
}
}
private:
~Nasty() {}
size_t references;
};
// Usage
Nasty * nasty = new Nasty; // 1 reference
nasty->acquire(); // get a second reference
nasty->release(); // back to one
nasty->release(); // deleted
nasty->acquire(); // BOOM!
I would prefer to use std::shared_ptr for this purpose, since it's thread-safe, exception-safe, works for any type without needing any explicit support, and prevents access after deleting.
More usefully, it could be used in an event-driven system, where objects are created, and then manage themselves until they receive an event that tells them that they're no longer needed:
class Worker : EventReceiver {
public:
Worker() {
start_receiving_events(this);
}
virtual void on(WorkEvent) {
do_work();
}
virtual void on(DeleteEvent) {
stop_receiving_events(this);
delete this;
}
private:
~Worker() {}
void do_work();
};
1) Why would I want to force the object to be made on the heap instead of on the stack?
1) Because the object's lifetime is not logically tied to a scope (e.g., function body, etc.). Either because it must manage its own lifespan, or because it is inherently a shared object (and thus, its lifespan must be attached to those of its co-dependent objects). Some people here have pointed out some examples like event handlers, task objects (in a scheduler), and just general objects in a complex object hierarchy.
2) Because you want to control the exact location where code is executed for the allocation / deallocation and construction / destruction. The typical use-case here is that of cross-module code (spread across executables and DLLs (or .so files)). Because of issues of binary compatibility and separate heaps between modules, it is often a requirement that you strictly control in what module these allocation-construction operations happen. And that implies the use of heap-based objects only.
2) Is there another use of delete this apart from this? (supposing that this is a legitimate use of it :) )
Well, your use-case is really just a "how-to" not a "why". Of course, if you are going to use a delete this; statement within a member function, then you must have controls in place to force all creations to occur with new (and in the same translation unit as the delete this; statement occurs). Not doing this would just be very very poor style and dangerous. But that doesn't address the "why" you would use this.
1) As others have pointed out, one legitimate use-case is where you have an object that can determine when its job is over and consequently destroy itself. For example, an event handler deleting itself when the event has been handled, a network communication object that deletes itself once the transaction it was appointed to do is over, or a task object in a scheduler deleting itself when the task is done. However, this leaves a big problem: signaling to the outside world that it no longer exists. That's why many have mentioned the "intrusive reference counting" scheme, which is one way to ensure that the object is only deleted when there are no more references to it. Another solution is to use a global (singleton-like) repository of "valid" objects, in which case any accesses to the object must go through a check in the repository and the object must also add/remove itself from the repository at the same time as it makes the new and delete this; calls (either as part of an overloaded new/delete, or alongside every new/delete calls).
However, there is a much simpler and less intrusive way to achieve the same behavior, albeit less economical. One can use a self-referencing shared_ptr scheme. As so:
class AutonomousObject {
private:
std::shared_ptr<AutonomousObject> m_shared_this;
protected:
AutonomousObject(/* some params */);
public:
virtual ~AutonomousObject() { };
template <typename... Args>
static std::weak_ptr<AutonomousObject> Create(Args&&... args) {
std::shared_ptr<AutonomousObject> result(new AutonomousObject(std::forward<Args>(args)...));
result->m_shared_this = result; // link the self-reference.
return result; // return a weak-pointer.
};
// this is the function called when the life-time should be terminated:
void OnTerminate() {
m_shared_this.reset( NULL ); // do not use reset(), but use reset( NULL ).
};
};
With the above (or some variations upon this crude example, depending on your needs), the object will be alive for as long as it deems necessary and that no-one else is using it. The weak-pointer mechanism serves as the proxy to query for the existence of the object, by possible outside users of the object. This scheme makes the object a bit heavier (has a shared-pointer in it) but it is easier and safer to implement. Of course, you have to make sure that the object eventually deletes itself, but that's a given in this kind of scenario.
2) The second use-case I can think of ties in to the second motivation for restricting an object to be heap-only (see above), however, it applies also for when you don't restrict it as such. If you want to make sure that both the deallocation and the destruction are dispatched to the correct module (the module from which the object was allocated and constructed), you must use a dynamic dispatching method. And for that, the easiest is to just use a virtual function. However, a virtual destructor is not going to cut it because it only dispatches the destruction, not the deallocation. The solution is to use a virtual "destroy" function that calls delete this; on the object in question. Here is a simple scheme to achieve this:
struct CrossModuleDeleter; //forward-declare.
class CrossModuleObject {
private:
virtual void Destroy() /* final */;
public:
CrossModuleObject(/* some params */); //constructor can be public.
virtual ~CrossModuleObject() { }; //destructor can be public.
//.... whatever...
friend struct CrossModuleDeleter;
template <typename... Args>
static std::shared_ptr< CrossModuleObject > Create(Args&&... args);
};
struct CrossModuleDeleter {
void operator()(CrossModuleObject* p) const {
p->Destroy(); // do a virtual dispatch to reach the correct deallocator.
};
};
// In the cpp file:
// Note: This function should not be inlined, so stash it into a cpp file.
void CrossModuleObject::Destroy() {
delete this;
};
template <typename... Args>
std::shared_ptr< CrossModuleObject > CrossModuleObject::Create(Args&&... args) {
return std::shared_ptr< CrossModuleObject >( new CrossModuleObject(std::forward<Args>(args)...), CrossModuleDeleter() );
};
The above kind of scheme works well in practice, and it has the nice advantage that the class can act as a base-class with no additional intrusion by this virtual-destroy mechanism in the derived classes. And, you can also modify it for the purpose of allowing only heap-based objects (as usually, making constructors-destructors private or protected). Without the heap-based restriction, the advantage is that you can still use the object as a local variable or data member (by value) if you want, but, of course, there will be loop-holes left to avoid by whoever uses the class.
As far as I know, these are the only legitimate use-cases I have ever seen anywhere or heard of (and the first one is easily avoidable, as I have shown, and often should be).
The general reason is that the lifetime of the object is determined by some factor internal to the class, at least from an application viewpoint. Hence, it may very well be a private method which calls delete this;.
Obviously, when the object is the only one to know how long it's needed, you can't put it on a random thread stack. It's necessary to create such objects on the heap.
It's generally an exceptionally bad idea. There are a very few cases- for example, COM objects have enforced intrusive reference counting. You'd only ever do this with a very specific situational reason- never for a general-purpose class.
1) Why would I want to force the object to be made on the heap instead of on the stack?
Because its life span isn't determined by the scoping rule.
2) Is there another use of delete this apart from this? (supposing that this is a legitimate use of it :) )
You use delete this when the object is the best placed one to be responsible for its own life span. One of the simplest example I know of is a window in a GUI. The window reacts to events, a subset of which means that the window has to be closed and thus deleted. In the event handler the window does a delete this. (You may delegate the handling to a controller class. But the situation "window forwards event to controller class which decides to delete the window" isn't much different of delete this, the window event handler will be left with the window deleted. You may also need to decouple the close from the delete, but your rationale won't be related to the desirability of delete this).
delete this;
can be useful at times and is usually used for a control class that also controls the lifetime of another object. With intrusive reference counting, the class it is controlling is one that derives from it.
The outcome of using such a class should be to make lifetime handling easier for users or creators of your class. If it doesn't achieve this, it is bad practice.
A legitimate example may be where you need a class to clean up all references to itself before it is destructed. In such a case, you "tell" the class whenever you are storing a reference to it (in your model, presumably) and then on exit, your class goes around nulling out these references or whatever before it calls delete this on itself.
This should all happen "behind the scenes" for users of your class.
"Why would I want to force the object to be made on the heap instead of on the stack?"
Generally when you force that it's not because you want to as such, it's because the class is part of some polymorphic hierarchy, and the only legitimate way to get one is from a factory function that returns an instance of a different derived class according to the parameters you pass it, or according to some configuration that it knows about. Then it's easy to arrange that the factory function creates them with new. There's no way that users of those classes could have them on the stack even if they wanted to, because they don't know in advance the derived type of the object they're using, only the base type.
Once you have objects like that, you know that they're destroyed with delete, and you can consider managing their lifecycle in a way that ultimately ends in delete this. You'd only do this if the object is somehow capable of knowing when it's no longer needed, which usually would be (as Mike says) because it's part of some framework that doesn't manage object lifetime explicitly, but does tell its components that they've been detached/deregistered/whatever[*].
If I remember correctly, James Kanze is your man for this. I may have misremembered, but I think he occasionally mentions that in his designs delete this isn't just used but is common. Such designs avoid shared ownership and external lifecycle management, in favour of networks of entity objects managing their own lifecycles. And where necessary, deregistering themselves from anything that knows about them prior to destroying themselves. So if you have several "tools" in a "toolbelt" then you wouldn't construe that as the toolbelt "owning" references to each of the tools, you think of the tools putting themselves in and out of the belt.
[*] Otherwise you'd have your factory return a unique_ptr or auto_ptr to encourage callers to stuff the object straight into the memory management type of their choice, or you'd return a raw pointer but provide the same encouragement via documentation. All the stuff you're used to seeing.
A good rule of thumb is not to use delete this.
Simply put, the thing that uses new should be responsible enough to use the delete when done with the object. This also avoids the problems with is on the stack/heap.
Once upon a time i was writing some plugin code. I believe i mixed build (debug for plugin, release for main code or maybe the other way around) because one part should be fast. Or maybe another situation happened. Such main is already released built on gcc and plugin is being debugged/tested on VC. When the main code deleted something from the plugin or plugin deleted something a memory issue would occur. It was because they both used different memory pools or malloc implementations. So i had a private dtor and a virtual function called deleteThis().
-edit- Now i may consider overloading the delete operator or using a smart pointer or simply just state never delete a function. It will depend and usually overloading new/delete should never be done unless you really know what your doing (dont do it). I decide to use deleteThis() because i found it easier then the C like way of thing_alloc and thing_free as deleteThis() felt like the more OOP way of doing it