Sign in to follow this  

Java/c++, use singletons for global classes?

This topic is 4378 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi, using the languages c++,java... I was wondering if I should use singletons for classes that need to be accessed globally? eg Timer, Mouse, Keyboard, Data(if data-centred). If not, what would you do to allow access to these kinds of classes that need to be accessed globally? Thanks

Share this post


Link to post
Share on other sites
if i understand correctly you want objects that can be accessed by any file in the source code. method 1 is using externs in C++ but I hate externd and method 2 is best (C++):

in Utilities.h:

#prgama once
class Utilities
{
public:
static Mouse _mouse;
static Keyboard _Keyboard;
static Timer _timer;

static void Update(void); //if needed to update the static objects:
};



in Utilities.cpp:

#include "Utilities.h"

Mouse Utilities::_mouse;
Keyboard Utilities::_Keyboard;
Timer Utilities::_timer;

void Utilities::Update(void)
{
//update the mouse , timer and keyboard here
}



now in any file u can access the objects:
by first including Uitlities.h then:

lets say you want to check the mouse:

if(Utilities::_mouse.IsClick())
{
//do something
}


I hope i understood what you wanted.

Share this post


Link to post
Share on other sites
I've used externs like that before, but I want to use the same style of code for java aswell. I'm not sure but I don't think java does anything like extern.

I think some people would frown upon using static classes, im not sure why though.
Thanks

Share this post


Link to post
Share on other sites
Method 2 using static members requires declaration and definition of all data members.
You can get rid of the static parts when using a class instance like this:

in utils.h:

#ifndef UTILS_H
#define UTILS_H

struct Utils {
Mouse mouse;
Keyboard keyboard;
};

static inline
Utils& getUtils() {
extern Utils utils;
return utils;
}

#endif

in utils.cc:

Utils utils;


You may also want to search for 'singleton' pattern.

Share this post


Link to post
Share on other sites
Often I just use namespaces...



header:

namespace SomeSingletonSortaThing
{
extern int some_property0;
extern std::string some_property1;
extern std::string some_property2;

int some_method0();
int some_method1( std::string const& text );
}




source:

namespace SomeSingletonSortaThing
{
int some_property0;
std::string some_property1;
std::string some_property2;
}

int SomeSingletonSortaThing::some_method0()
{
return 42;
}

int SomeSingletonSortaThing::some_method1( std::string const& text )
{
return 84;
}


Share this post


Link to post
Share on other sites
hmm, i really think static class members is the way to go.
externs need to be extrned in every file.
namespacing is also good .. but the reason i use static members is managing them is easy (maybe for me).

Share this post


Link to post
Share on other sites
Quote:
I'm not sure but I don't think java does anything like extern.


Java doesn't need anything like extern as unlike C++ it doesn't need header files and you don't have to declare something before you can use it in a translation unit.

Personally I'd just have a global pointer to an instance of the class. That way if you decide you want to have several instances of the class for some reason things will be easier to modify.

Share this post


Link to post
Share on other sites
Quote:
Original post by Monder
Quote:
I'm not sure but I don't think java does anything like extern.


Java doesn't need anything like extern as unlike C++ it doesn't need header files and you don't have to declare something before you can use it in a translation unit.

Personally I'd just have a global pointer to an instance of the class. That way if you decide you want to have several instances of the class for some reason things will be easier to modify.


Monder's right. If you can think of any reason that you'd want multiple instances of a class, use a singleton pattern in Java. But, if you are certain you'll never need more than 1 instance, Java has static methods/fields.

public class Test {
public static void doSomething();
}


Then from any point within your project, import Test and call:

Test.doSomething(); // Notice left-side of the . operator is not an instance of an object, but a class name.


Share this post


Link to post
Share on other sites
I suggest you limit your use of globals regardless of which technique used to implement them. People tend to access globals when they need them, in any context, coupling more code than necessary.

For instance:


class UpdateContext
{
const Timer& m_timer;
const Keyboard& m_keyboard;
const Mouse& m_mouse;
...
};

class RenderContext
{
RenderMgr& m_render_mgr;
Camera& m_camera;
};

void Update(const UpdateContext& context)
{
...
}

void Render(const RenderContext& context)
{
...
}


Share this post


Link to post
Share on other sites
Hi, this is the way I made my C++ game engine global.


// ENGINELIBRARY.H

//include common library headers
//..

//include API specific headers
//..

//include engine specific headers
#include "Graphics.h"
#include "Sound.h"
#include "Input.h"
#include "Network.h"

//lastly include the engine core
#include "MyEngine.h"





// MYENGINE.H

class MYENGINE
{
public:
MYENGINE();
~MYENGINE();

GRAPHICS graphics;
SOUND sound;
INPUT input;
NETWORK network;
};

extern MYENGINE *engine;




// MYENGINE.CPP

MYENGINE *engine = NULL;

MYENGINE::MYENGINE()
{
//Initialize engine components
//graphics.Initialize(...)
//yada yada...
}

MYENGINE::~MYENGINE()
{
//shutdown components...
}



Then all the files that include "EngineLibary.h" have access to the engine. Just be sure call engine = new MYENGINE() before using it. To access any component just call engine->graphics, engine->input, etc...

Hope this helps.

Share this post


Link to post
Share on other sites
An alternative is to create instances of all those services, and put them somewhere where you can look them up -- say, in an "environment" class. This class could just have a bunch of pointers, or it could be a hashtable from typeinfo to instance (wrapped in a template for type safety).

The benefit of doing that is that you can have more than one instance of whatever your main application functions are, within the same process. For example, you could run two game clients and one game server in the same process, for testing networking. You could also have different execution environments for different threads (to avoid locking), or have a restricted execution environment for scripting code.

Share this post


Link to post
Share on other sites

This topic is 4378 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this