Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

I'm working on my own game engine and I am currently designing my managers. And I've read that for memory management using Init() and CleanUp() functions are better then using Constructors and Destructor. So I was wondering how Init() and CleanUp() work? And how can I implement them into my engine?

edit: I am mainly looking for code examples (preferably c++), or links to examples, to see how those functions work and how I can implement them into my engine..

share|improve this question

4 Answers 4

up vote 7 down vote accepted

It's pretty simple, actually:

Instead of having a Constructor which does your setup,

// c-family pseudo-code
public class Thing {
    public Thing (a, b, c, d) { this.x = a; this.y = b; /* ... */ }
}

...have your constructor do little or nothing at all, and write a method called .init or .initialize, which would do what your constructor would normally do.

public class Thing {
    public Thing () {}
    public void initialize (a, b, c, d) {
        this.x = a; /*...*/
    }
}

So now instead of just going like:

Thing thing = new Thing(1, 2, 3, 4);

You can go:

Thing thing = new Thing();

thing.doSomething();
thing.bind_events(evt_1, evt_2);
thing.initialize(1, 2, 3, 4);

The benefit there is that you can now use dependency-injection/inversion-of-control more-easily in your systems.

Instead of saying

public class Soldier {
    private Weapon weapon;

    public Soldier (name, x, y) {
        this.weapon = new Weapon();
    }
}

You can build the soldier, give him an equip method, where you hand him a weapon, and THEN call all of the rest of the constructor functions.

So now, instead of subclassing enemies where one soldier has a pistol and another has a rifle and another has a shotgun, and that's the only difference, you can just say:

Soldier soldier1 = new Soldier(),
        soldier2 = new Soldier(),
        soldier3 = new Soldier();

soldier1.equip(new Pistol());
soldier2.equip(new Rifle());
soldier3.equip(new Shotgun());

soldier1.initialize("Bob",  32,  48);
soldier2.initialize("Doug", 57, 200);
soldier3.initialize("Mike", 92,  30);

Same deal with destruction. If you have special needs (removing event listeners, removing instances from arrays/whatever structures you're working with, etc), you would then manually call them, so that you know exactly when and where in the program that was happening.

EDIT


As Kryotan has pointed out, below, this answers the original post's "How", but doesn't really do a good job of a "Why".

As you can probably see in the answer above, there might not be much of a difference between:

var myObj = new Object();
myObj.setPrecondition(1);
myObj.setOtherPrecondition(2);
myObj.init();

and writing

var myObj = new Object(1,2);

while just having a larger constructor function.
There is an argument to be made for objects which have 15 or 20 pre-conditions, which would make a constructor very, very hard to work with, and it would make things easier to see and remember, by pulling those things out into the interface, so that you can see how the instantiation works, one level higher.

Optional-configuration of objects is a natural extension to this; optionally setting values on the interface, before making the object run.
JS has some great shortcuts for this idea, which just seem out of place in stronger-typed c-like languages.

That said, chances are, if you're dealing with an argument list that long in your constructor, that your object is too big and does too much, as is. Again, this is a personal-preference thing, and there are exceptions far and wide, but if you're passing 20 things into an object, chances are good that you could find a way to make that object do less, by making smaller objects.

A more-pertinent reason, and one which is widely-applicable would be that the initialization of an object relies on asynchronous data, which you don't have, currently.

You know that you need the object, so you're going to create it anyway, but in order to have it function properly, it needs data from the server, or from another file which it now needs to load.

Again, whether you're passing the needed data into a gigantic init, or building out an interface isn't really important to the concept, so much as it's important to the interface of your object, and the design of your system...

But in terms of building the object, you might do something like this:

var obj_w_async_dependencies = new Object();
async_loader.load(obj_w_async_dependencies.async_data, obj_w_async_dependencies);

async_loader might get passed a filename, or a resource name or whatever, load that resource -- maybe it loads sound files, or image data, or maybe it loads saved character stats...

...and then it would feed that data back into obj_w_async_dependencies.init(result);.

This sort of dynamic is found frequently in web-apps.
Not necessarily in an object's construction, for higher-level applications: for example, galleries might load and initialize right away, and then display photos as they stream in -- that's not really an async-initialization, but where it's seen more frequently would be in JavaScript libraries.

One module might depend on another, and so the initialization of that module might be deferred until the loading of the dependants is complete.

In terms of game-specific instances of this, consider an actual Game class.

Why can't we call .start or .run in the constructor?
Resources need to be loaded -- the rest of everything has pretty much been defined and is good to go, but if we try running the game without a database-connection, or without textures or models or sounds or levels, it's not going to be a particularly interesting game...

...so what, then is the difference between what we see of a typical Game, except that we give its "go ahead" method a name which is more interesting than .init (or conversely, break the initialization even further apart, to separate loading, setting up the things which have been loaded, and running the program when everything has been set up).

share|improve this answer
2  
"you would then manually call them, so that you know exactly when and where in the program that was happening." The only time in C++ where a destructor would be implicitly called is for a stack object (or global). Heap allocated objects require explicit destruction. So it's always clear when the object is being deallocated. –  Nicol Bolas Jan 31 '13 at 18:25
4  
It's not exactly accurate to say that you need this separate method to enable the injection of different weapon types, or that this is the only way to avoid proliferation of subclasses. You can pass the weapon instances in via the constructor! So it's a -1 from me as this is not a compelling use case. –  Kylotan Jan 31 '13 at 18:57
    
-1 From me as well, for pretty much the same reasons as Kylotan. You don't make a very compelling argument, all this could have been done with constructors. –  Paul Manta Jan 31 '13 at 19:13
    
Yes, it could be accomplished with constructors and destructors. He asked for use-cases of a technique and why and how, rather than how they work or why they do. Having a component-based system where you have setter/binding methods, versus constructor-passed parameters for DI really all comes down to how you want to build your interface. But if your object requires 20 IOC components, do you want to put ALL of them into your constructor? Can you? Of course you can. Should you? Maybe, maybe not. If you choose not to, then do you need a .init, maybe not, but likely. Ergo, valid case. –  Norguard Jan 31 '13 at 19:34
1  
@Kylotan I actually edited the title of the question to ask why. The OP only asked "how". I extended the question to include the "why" as the "how" is trivial to anybody who knows anything about programming ("Just move the logic you would have into the ctor into a separate function and call it") and the "why" is more interesting/general. –  Tetrad Jan 31 '13 at 21:35

Whatever you read that said Init and CleanUp is better, should have also told you why. Articles that don't justify their claims are not worth reading.

Having separate initialisation and shutdown functions can make it easier to set up and destroy systems because you can choose what order to call them in, whereas constructors get called exactly when the object is created and destructors called when the object is destroyed. When you have complex dependencies between 2 objects you often need them both to exist before they set themselves up - but often this is a sign of poor design elsewhere.

Some languages don't have destructors that you can rely on, since reference counting and garbage collection make it harder to know when the object will be destroyed. In these languages you almost always need a shutdown/cleanup method, and some like to add the init method for symmetry.

share|improve this answer
    
Thank you, but I'm mainly looking for examples, since the article didn't have them. I apologize if my question was unclear about that, but I have edited it now. –  Friso1990 Jan 31 '13 at 17:22

I think the best reason is : to allow pooling.
if you have Init and CleanUp, you can, when an object is killed, just call CleanUp, and push the object onto a stack of object of the same type : a 'pool'.
Then, whenever you need a new object, you can pop one object from the pool OR if the pool is empty -too bad- you have to create a new one. Then you call Init on this object.
A good strategy is to pre-fill the pool before the game begins with a 'good' number of objects, so you never have to create any pooled object during the game.
If, on the the other hand, you use 'new', and just stop referencing an object when it is of no use to you, you create garbage that must be recollected at some time. This recollection is especially a bad thing for single-threaded languages like Javascript, where the garbage collector stops all the code when it evaluates it needs to recollects the memory of the objects no longer in use. The game hangs during a few milliseconds, and playing experience is spoiled.
- You allready understood - : if you pool all your objects, no recollection happens, hence no more random slow-down.

It is also much faster to call init on an object coming from the pool than to allocate memory + init a new object.
But the speed improvement has less importance, since quite often object creation is not a performance bottleneck... With a few exceptions, like frantic games, particle engines, or physic engine using intensively 2D/3d vectors for their computations. Here both speed and garbage creation are greatly improved by using a pool.

Rq : you might not need to have a CleanUp method for your pooled objects if the Init() resets everything.

Edit : replying to this post motivated me to finalize a little article i made about pooling in Javascript.
You can find it here if you're interested :
http://gamealchemist.wordpress.com/

share|improve this answer
1  
-1: You don't need to do this just to have a pool of objects. You can do that by just separating allocation from construction via placement new and deallocation from deletion by an explicit destructor call. So this is not a valid reason to separate constructors/destructors from some initializer method. –  Nicol Bolas Feb 1 '13 at 0:24
    
placement new is C++ specific, and a bit esoteric as well. –  Kylotan Feb 1 '13 at 0:52
    
+1 it may be possible to do this in other way in c+. But not in other languages... and this is probably only reason why I would use Init method on gameobjects. –  Kikaimaru Feb 1 '13 at 8:25
    
@Nicol Bolas : i think you're overreacting. The fact that there are other ways to do pooling (you mention a complex one, specific to C++) does not invalidate the fact that using a separate Init is a nice and simple way to implement pooling in many languages. my preferences goes, on GameDev, to more generic answers. –  GameAlchemist Feb 1 '13 at 9:31
    
@VincentPiel: How is using placement new and such "complex" in C++? Also, if you're working in a GC language, odds are good that objects will contain GC-based objects. So will they also have to poll each of them? Thus, creating a new object will involve getting a bunch of new objects from pools. –  Nicol Bolas Feb 1 '13 at 9:40

Your question is reversed... Historically speaking, the more pertinent question is:

Why is construction + intialisation conflated, i.e. why don't we do these steps separately? Surely this goes against SoC?

For C++, RAII's intent is that resource acquisition and release be tied directly to object lifetime, in the hopes that this will assure resource release. Does it? Partly. It is 100% fulfilled in the context of stack-based / automatic variables, where leaving the associated scope automatically calls destructors / releases these variables (hence the qualifier automatic). However for heap variables, this very useful pattern sadly breaks down, since you are still forced to explicitly call delete in order to run the destructor, and if you forget to do so you will still be bitten by what RAII attempts to solve; in context of heap-allocated variables, then, C++ provides limited benefit over C (delete vs free()) while conflating construction with initialisation, which negatively impacts in terms of the following:

Building an object system for games / simulations in C is strongly recommended in that it will shed a great deal of light on the limitations of RAII and other such OO-centric patterns through a deeper understanding of the assumptions that C++ and later classical OO languages make (remember that C++ started out as a an OO system built in C).

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.