0

I am currently writing a little textbase advendture game where I want to create all GameObjects centrally so that I can use shallow copies of them later on to save some memory. The way I doing that now is creating a static instance in an extra header file wich will than be deleted when the program terminates.

Here is a simplified example of what I'm doing right now:

#ifndef OBJECTS_H_
#define OBJECTS_H_

#include "GameObject.h"

#include <iostream>

static GameObject *apple = new GameObject("Apple", [] () { std::cout << "Delicous apple!" << std::endl; return true; });

void deleteAll()
{
    delete apple;
}

#endif

main.cpp:

#include <iostream>
#include <vector>
#include "GameObject.h"

#include "Objects.h"

using namespace std;

int main()
{
    std::vector<GameObject*> objects{apple, apple};

    try
    {
        objects[0]->use();
        objects[1]->use();
    }
    catch (const GameObjectException &goe)
    {
        cout << goe.what() << endl;
    }

    deleteAll();
}

Is there a more elegant way of achieving this?

muXXmit2X
  • 2,745
  • 3
  • 17
  • 34
  • @MohitJain Code Review SE requires complete and working code. – πάντα ῥεῖ Feb 26 '16 at 11:00
  • Unless the `GameObject` destructor does something important (and it probably should not do something important!), there is no point in deleting it when the program ends. It may even be counter-productive. I don't think games run on operating systems which fail to clean up after a terminated process. – Christian Hackl Feb 26 '16 at 14:30
  • Other than that, you have fallen into the premature-optimisation trap. – Christian Hackl Feb 26 '16 at 14:32

3 Answers3

3

In Modern C++, you normally avoid saving raw pointers. In your case, you could use either std::shared_ptr or std::unique_ptr in your vector. I would probably use shared_ptr from what I see.

std::shared_ptr<GameObject> apple = std::make_shared <GameObject>("Apple", [] () { std::cout << "Delicous apple!" << std::endl; return true; });

You also wouldn't put that in the header file. You'd only have:

std::shared_ptr<GameObject> apple;

in the header, and the full declaration in a single .cpp file.

Rob L
  • 2,351
  • 13
  • 23
3

When you use static object in a header file, each translation unit where that header file is included will have it's very own instance of that static object, it will not be shared with the rest of the program.

If you have multiple source files, then instead of making the object static just declare them as extern then in a single source file you actually define the objects. I also recommend against declaring the objects as pointers to objects, instead just declare them as normal object instances. Use the address-of operator when you need a pointer, but try to avoid it and instead use references when you can.

Alternatively, if you create a vector of all objects, why declare the objects at all in the header file, unless you want to access some special objects? Instead you can create them all inline in the vector and then only declare the vector in the header file:

// In header file
extern std::vector<GameObject> objects;

// In source file (as a global variable)
std::vector<GameObject> object = {
    GameObject("Apple", [] () { std::cout << "Delicous apple!" << std::endl; return true; }),
    ...
};

If you need to use pointer, then use std::shared_ptr instead:

// In header file
extern std::vector<std::shared_ptr<GameObject>> objects;

// In source file (as a global variable)
std::vector<std::shared_ptr<GameObject>> object = {
    std::make_shared<GameObject>("Apple", [] () { std::cout << "Delicous apple!" << std::endl; return true; }),
    ...
};
Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

The problem with putting statics in header files is that the C preprocessor is just a fairly dumb macro expander. The upshot being that for every C file you include this in, the statement static object* = ... is expanded. This is equivalent to writing that statement in each cpp file. Not what you wanted.

What your looking for is the singleton pattern there's a good answer here on it Difference between static class and singleton pattern? which although was in answer to a question about static classes (utility classes) it applies here too.

The Loki library has a singleton template http://loki-lib.sourceforge.net/html/a00519.html which you could use or just use it as an example to roll your own simpler version.

There's an article here on the singleton pattern https://sourcemaking.com/design_patterns/singleton

Community
  • 1
  • 1
systemcpro
  • 856
  • 1
  • 7
  • 15