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! :)
Related
I have a collection of objects, lets say QVector<ApplicationStates>, which registers the most important operations done in my software. Basically, this object is meant to process redo/undo operations.The application is built using a lot of delegated objects. Operations which have to be registered lie in a lot of these objects. As such, I am always passing my collection of objects, in each delegate under the form:
class AWidget : public QWidget{
AWidget(QVector<ApplicationStates>* states, QWidget* parent = nullptr);
...
It seems ugly to me. I think about two solutions:
Singleton;
Simply declare the QVector as a static global variable (I read that global variables are evil).
Does someone have a suggestion?
Thanks for your answers.
I get into a similar situation from time to time, and I have found simply wrapping your vector in a class called something like "ApplicationContext" then passing a shared pointer or reference to an instance of that around saves the day. It has many benefits:
You avoid the global / singleton, and you are free to in fact have several instances concurrently in the future
If you suddenly have more than just that vector of objects that you need to pass arround, simply extend your context class to add whatever you need
If your vector suddenly becomes a map or changes in other ways, you need not change any interfaces that pass it along such as the signals/slots. (You will need to change the implementation where the vector is used of course).
BONUS: The code becomes easily testable! You can now make test cases for this class.
This might not be the best solution in all cases, but I think it comes pretty close in this case!
I have a class called Widget. This class is abstract and has virtual methods. To avoid object slicing all Widgets are stored as references or pointers. I have several classes with constructors that store internally the widget given to them; thus the Widget stored must have been initialized outside the constructor and cannot be destroyed before the object is, therefore usually the Widget is allocated via dynamic memory. My question is regarding how to handle this dynamic memory; I have compiled a list of options (feel free to suggest others.) Which is the most idiomatic?
1. Smart pointers. Smart pointers seem like the right choice, but since I'm using C++98 I have to write my own. I also think that writing smart_pointer<Widget> all the time is a little ugly.
2. Copy Widgets when stored. Another course of action is to store a copy of the passed-in Widget instead of the original. This might cause object-slicing, but I'm not sure. Also, users might want to write classes themselves that store passed-in Widgets, and I wouldn't want to make it too complicated.
3. Let the user handle everything. I could perhaps make the user make sure that the Widget is deleted on time. This seems to be what Qt does (?). However, this again complicates things for the user.
I personally like this approach (it is not always applicable, but I used it successfully multiple times):
class WidgetOwner
{
vector<Widget*> m_data;
public:
RegisterWidget(Widget *p) { m_data.push_back(p); }
~WidgetOwner() { for (auto &p : m_data) delete p; }
};
This simple class just stores pointers. This class can store any derivatives of Widget provided that Widget has virtual destructor. For a polymorphic class this should not be a problem.
Note that once Widget is registered, it cannot be destroyed unless everything is destroyed.
The advantage of this approach is that you can pass around pointers freely. They all will be valid until the storage will be destroyed. This is sort of hand made pool.
Which is the most idiomatic?
The most idiomatic would certainly be what next versions of c++ decided to be "the way to go", and that would be smart pointers (You can find/use an implementation on boost for example, also other ones on the internet might be simpler for inspiration).
You can also decide that since you are using c++98 (that's a huge factor to take into consideration), you take what's idiomatic for that context, and since that was pretty much no man's land, the answer is most likely whatever home made design is the most appealing to you.
I think smart pointer is best choice. And if you feel template is ugly, try the typedef
I was told to avoid using pointers in C++. It seems that I can't avoid them however in the code i'm trying to write, or perhaps i'm missing out on other great C++ features.
I wish to create a class (class1) which contains another class (class2) as a data member. I then want class2 to know about class1 and be able to communicate with it.
I could have a reference to class1 as a member in class2 but that then means I need to provide a reference to class1 as a parameter in the constructor of class2 and use initialiser lists which I don't want. I'm trying to do this without needing the constructor to do it.
I would like for class2 to have a member function called Initialise which could take in the reference to class1, but this seems impossible without using pointers. What would people recommend here? Thanks in advance.
The code is completely simplified just to get the main idea across :
class class1
{
public:
InitialiseClass2()
{
c2.Initialise(this);
}
private:
class2 c2;
};
class class2
{
public:
Initialise(class1* c1)
{
this->c1 = c1;
}
private:
class1* c1;
};
this seems impossible without using pointers
That is incorrect. Indeed, to handle a reference to some other object, take a reference into a constructor:
class class2
{
public:
class2(class1& c1)
: c1(c1)
{}
private:
class1& c1;
};
The key here is to initialise, not assign, the reference. Whether this is possible depends on whether you can get rid of your Initialise function and settle into RAII (please do!). After that, whether this is actually a good idea depends on your use case; nowadays, you can almost certainly make ownership and lifetime semantics much clearer by using one of the smart-pointer types instead — even if it's just a std::weak_ptr.
Anyway, speaking more generally.
Are pointers "always" bad? No, of course not. I'd almost be tempted to say that managing dynamic memory yourself is "always" bad, but I won't make a generalisation.
Should you avoid them? Yes.
The difference is that the latter is a guideline to steer you away from manual memory management, and the former is an attempted prohibition.
No, using pointers in C++ is not bad at all, and I see this anti-advice over and over again. What is bad is managing pointers by yourself, unless you are creating a pointer-managing low-level entity.
Again, I shall make a very clear distinction. Using pointers is good. Very few real C++ programs can do without USING pointers. Managing pointers is bad, unless you are working on pointer manager.
A pointer can be nullptr whereas a reference must always be bound to something (and cannot be subsequently re-bound to something else).
That's the chief distinction and the primary consideration for your design choice.
Memory management of pointers can be delegated to std::shared_ptr and std::unique_ptr as appropriate.
well, I never had the need to 2 classes to have reciprocal reference and for good reasons, how do you know how to test those classes? If later you need to change something in the way the 2 classes communicates you will probably have to change code in both classes). You can workaround in many ways:
You may need in reality just 1 class ( you have broken into much classes)
You can register a Observer for a class (using a 3rd class, in that case you will end up with a pointer, but at least the 2 classes are less coupled and it is easier test them).
You can think (maybe) to a new interface that require only 1 class to call methods on the other class
You could pass a lambda (or a functor if you do not have C++11) into one of the methods of the class removing the need to a back reference
You could pass a reference of the class inside a method.
Maybe you have to few classes and in reality you need a third class than communicates with both classes.
It is possible you need a Visitor (maybe you really need multiple dispatch)
Some of the workarounds above need pointers, some not. To you the choice ;)
NOTE: However what you are doing is perfectly fine to me (I see you do some trickery only in constructors, but probably you have more omitted code, in wich case that can cause troubles to you). In my case I "register" one class into another, then after the constructor called I have only one class calling the other and not viceversa.
First of all whenever you have a circular dependency in your design think about it twice and make sure it's the way to go. Try to use the Dependency inversion principle in order to analyze and fix your dependencies.
I was told to avoid using pointers in C++. It seems that I can't avoid them however in the code i'm trying to write, or perhaps i'm missing out on other great C++ features.
Pointers are a powerful programming tool. Like any other feature in the C++ (or in any programming language in general) they have to be used when they are the right tool. In C++ additionally you have access to references which are similar to pointers in usage but with a better syntax. Additionally they can't be null. Thus they always reference a valid object.
So use pointers when you ever need to but try to avoid using raw pointers and prefer a smart pointer as alternative whenever possible. This will protect you against some trivial memory leak problems but you still have to pay attention to your object life-cycle and for each dynamically allocated object you should know clearly who create it and when/whom will release the memory allocated for the object.
Pointers (and references) are very useful in general because they could be used to pass parameters to a method by reference so you avoid passing heavy objects by value in the stack. Imagine the case for example that you have a very big array of heavy objects (which copy/= operator is time consuming) and you would like to sort these objects. One simple method is to use pointers to these objects so instead of moving the whole object during the sorting operation you just move the pointers which are very lightweight data type (size of machine address basically).
What is a good way to share an instance of an object between several classes in a class hierarchy? I have the following situation:
class texture_manager;
class world {
...
std::vector<object> objects_;
skybox skybox_;
}
I currently implemented texture_manager as a singleton, and clients call its instancing method from anywhere in the code. texture_manager needs to be used by objects in the objects_ vector, by skybox_, and possibly by other classes as well that may or may not be part of the world class.
As I am trying to limit the use of singletons in my code, do you recommend any alternatives to this approach? One solution that came to mind would be to pass a texture_manager reference as an argument to the constructors of all classes that need access to it. Thanks.
The general answer to that question is to use ::std::shared_ptr. Or if you don't have that, ::std::tr1::shared_ptr, or if you don't have that, ::boost::shared_ptr.
In your particular case, I would recommend one of a few different approaches:
One possibility is, of course, the shared_ptr approach. You basically pass around your pointer to everybody who needs the object, and it's automatically destroyed when none of them need it anymore. Though if your texture manager is going to end up with pointers to the objects pointing at it, you're creating a reference cycle, and that will have to be handled very carefully.
Another possibility is just to declare it as a local variable in main and pass it as a pointer or reference to everybody who needs it. It won't be going away until your program is finished that way, and you shouldn't have to worry about managing the lifetime. A bare pointer or reference is just fine in this case.
A third possibility is one of the sort of vaguely acceptable uses of something sort of like a singleton. And this deserves a detailed explanation.
You make a singleton who's only job is to hand out useful pointers to things. A key feature it has is the ability to tell it what thing to hand out a pointer to. It's kind of like a global configurable factory.
This allows you to escape from the huge testing issues you create with a singleton in general. Just tell it to hand out a pointer to a stub object when it comes time to test things.
It also allows you to escape from the access control/security issue (yes, they create security issues as well) that a singleton represents for the same reason. You can temporarily tell it to pass out a pointer to an object that doesn't allow access to things that the section of code you're about to execute doesn't need access to. This idea is generally referred to as the principle of least authority.
The main reason to use this is that it saves you the problem of figuring out who needs your pointer and handing it to them. This is also the main reason not to use it, thinking that through is good for you. You also introduce the possibility that two things that expected to get the same pointer to a texture manager actually get pointers to a different texture manager because of a control flow you didn't anticipate, which is basically the result of the sloppy thinking that caused you to use the Singleton in the first place. Lastly, Singletons are so awful, that even this more benign use of them makes me itchy.
Personally, in your case, I would recommend approach #2, just creating it on the stack in main and passing in a pointer to wherever it's needed. It will make you think more carefully about the structure of your program, and this sort of object should probably live for your entire program's lifetime anyway.
Okay: I'm fairly new to C++ and static languages on a whole. Coming from years of ruby (and other dynamic languages) I don't know if this is possible.
I've been making a game state system for... well a game. I want to make the system easy for me to cut and paste into other games without any (or very few) changes.
The two things I am wanting to improve are the way in which states switch and the way in which state pointers are held.
There could be any number of states, but there will always be at least 2 to 3 states active in memory.
Ugliness No 1.
Currently I have a state manager class with something like this in it:
void StateManager::changeState(StateID nextStateID)
{
// UNFOCUS THE CURRENT STATE //
if (currentState())
{
currentState()->onUnFocus();
// DESTROY THE STATE IF IT WANTS IT //
if(currentState()->isDestroyedOnUnFocus()) {
destroyCurrentState();
}
}
if (m_GameStates[nextStateID]) {
// SWITCH TO NEXT STATE //
setCurrentState(nextStateID);
}
else
{
// CREATE NEW STATE //
switch (nextStateID)
{
case MainMenuStateID:
m_GameStates[MainMenuStateID] = new MainMenuState;
break;
case GameStateID:
m_GameStates[MainMenuStateID] = new GameStates;
break;
};
setCurrentState(nextStateID);
}
// FOCUS NEXT STATE //
currentState()->onFocus();
}
This approach works but I don't feel it's very nice.
Is it possible to pass a type? And then call new on it?
new NextGameState; // Whatever type that may be.
Can poloymophism help here? All States are derived from a class State.
Ugliness No 2.
Another thing I think needs some improvement is the way I've been storing the states.
State* m_GameStates[MaxNumberOfStates];
All the states are initialized to NULL, so I can test if a state is there, and if not it creates one when needed.
It works well as I can call the current state:
m_GameStates[m_CurrentState];
However, I don't like this for two reasons. It seems a bit of a waste having an array full of NULL pointers when there will only be 2 or 3 pointers active at any one time. [Editor's note: what is the second reason?]
I thought about shifting this into a vector_ptr, but didn't as it would create extra complications with checking to see if a state exists. And the vector seems to reinforce Ugliness No 1. as I need to have a list to check each state.
Any advice or direction appreciated.
Thanks,
Phil.
Use a enum(eration) to define all possible states (its something like a list with constants).
Just create for one object one variable that holds the state and change the variable whenever you need to change it.
As soon as you say States, I think of the State pattern.
Basically, you can derive a bunch of objects from a State base class. All actions related to a state occur against the current state maintained by the state manager. States will move from state to state via the manager.
For instance, you can have a Paused and Unpaused state, each with a buttonPressed event. When you press a button, the current state is delivered the event. If it's in Paused, and the button was the pause button, move to Unpaused. Vice versa for Unpaused.
void StateManager::changeState(StateID nextStateID)
{
leaveState(actualState);
enterState(nextStateID);
}
I really like this one - as easy as it could be. ;-)
What I want to tell you - I think doing creation/deleting your stats in the changeState Function is too much of logic in there - it just is supposed to change the state, right?
Edit:
To come to your 2 question - I don't think using this array is really a waste - you are talking about 3 fields, not 300 or so. So if you like using arrays - go for it. If you don't, the map would be my choose, it makes things easy if you want to check if there is a state created or not and you are not limited to a magic number "maxStates". You could possible check if there is enough ram and then create X states, not fixed 2-3.
For generating states you want a factory. That way the state id stays nice an generic. For storing states I would go with a std::map
For your first problem, yes, you can pass in a type, with some caveats.
I've added a comment under your question, asking for a bit more information. Until we get that, I can't really say how it should be done, but read up on templates.
You can make a function template, which can be passed a type, for example like this:
template <typename T>
void Foo() {
T* x = new T();
...
}
Foo<int>() // call Foo with the type T set to 'int'
There are some limitations to this, as the types have to be specified at compile-time, but it is a very powerful language feature.
Another option, which might work better since you seem to have an association between a variable (MainState) and a type (MainMenu), might be the use of traits classes. Again, I'm unsure of exactly how it'd be done in your case, since we haven't seen the entirety of the function (in particular, what type is MainState, and how/when is it created?)
It might also be possible to solve the problem through polymorphism, but again, I'd need to see a bit more of the context to suggest a solution.
For your second problem, you can use the standard library map:
#include <map>
// I'm not sure what type m_CurrentState is, so use its type instead of KeyType below
std::map<KeyType, State*> m_GameStates;
// and to perform a lookup in the map:
GameStates[m_CurrentState];
Finally, a really really important bit of advice:
Stop using pointers everywhere. Stop calling new to create new objects.
As a general rule, objects should be created on the stack (Instead of Foo* f = new Foo;, just do Foo f;
And instead of using pointers, you'll often want to just copy the object itself. Alternatively, create references instead of pointers.
And when you do need to use dynamic memory allocations, you still shouldn't use new directly. Instead, create a wrapper object, which internally allocates what it needs with new in its constructor, and frees it again in the destructor.
If you do this correctly, it pretty much solves all the headaches of memory management.
The general technique is called RAII.
Take a look at Boost Statechart Library