Jump to content
  • Advertisement

Archived

This topic is now archived and is closed to further replies.

jag_oes

I do not know how to implement a Singleton Class

This topic is 6062 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

I can''t find any good information of how I can implement a singleton class. I want a class to have one instance (called "Math"). The class just holds a bunch of math functions that are not in math.h as well as some more constants. It seems a singleton class would be best for this since I only need one global object to have access to the constants and functions but I cant find out how to implement it. Can anyone show me? Thanks

Share this post


Link to post
Share on other sites
Advertisement
This is how I do it, I'm assuming that this is a correct way to do it.

In the header file
    
class CLASSNAME
{
public:
static CLASSNAME *GetClass ();
private:
static CLASSNAME *single;
};


Then in the source file
  
CLASSNAME *CLASSNAME::single = 0;

CLASSNAME *CLASSNAME::GetClass ()
{
if (single == 0)
{
single = new CLASSNAME;
}

return single;
}


Now when you create a new class, do it like this

CLASSNAME *Instance = CLASSNAME::GetClass();
[/source]

Hope that helps.

Edited by - Lunatic Raven on February 22, 2002 10:58:44 PM

Share this post


Link to post
Share on other sites
        
// header


class Singleton
{
static Singleton* instance;
Singleton(); // private so nobody creates a Singleton object

public:
static Singleton& GetInstance();
};

// source


Singleton *Singleton::instance = NULL;

Singleton& Singleton::GetInstance()
{
if( !instance ) instance = new Singleton;
return *instance;
}


You can also use a class template, so long as you remember to define one variable in a source file for each template instance.


Edited by - Fruny on February 22, 2002 11:02:55 PM

Share this post


Link to post
Share on other sites
Thanks for the quick replies, the code helped a lot. But, now I am getting errors in my code. It is mainly because it thinks I do not have an instance of the math class. Here is what I have:

// HEADER


class Math_Singleton
{
private:


static Math_Singleton* instance;
Math_Singleton ();


public:


static Math_Singleton& Get_Instance ();
};


// SOURCE


Math_Singleton *Math_Singleton::instance = NULL;


Math_Singleton& Math_Singleton::Get_Instance ()
{
if (! instance)
{
instance = new Math_Singleton;


// initialize math constants
instance->pi = 3.14159265358f;
instance->e = 2.71828182846f;
instance->trans = PI / 180.0f;
}


return (*instance);
}


Math_Singleton Math = Math_Singleton::Get_Instance ();

Whenever I try using the Math object I get an undeclared identifier error. I have included the .h and everything ... do any of you know what is wrong?

Thanks for the help so far.

Edited by - jag_oes on February 22, 2002 11:58:23 PM

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
try doing the following for the last line
classname classinstancename = classname.GetInstance();


Try that.

Share this post


Link to post
Share on other sites
Well, since Math is a singleton, you cannot create a variable of its type.

You will have to create a reference to it, or use the GetInstance() function call everytime.

i.e.
MathSingleton& Math = MathSingleton::GetInstance();
float foo = Math.pi;

or
float foo = MathSingleton::GetInstance().pi 


But if all you wanted were constants, you could as well have put them in a namespace :


namespace Math
{
const float pi = 3.1415;
}

float foo = Math::pi

Share this post


Link to post
Share on other sites
@fruny: how can I make a template class for singletons ?
I tried to do and failed because my compiler created a new class for each .cpp file like this:

    
//main.cpp:


// main func

{
Singleton<COptions>::GetInstance.SetPlayers( 8 );

output();
}

//second.cpp:


void output()
{
cout << Singleton<COptions>::GetInstance.PlayerCount();
}


results in 0 as output given the fact that zero is the standard.

My problem was that static variables were not really static but unique for each source file.

Jan Rehders
http://www.turtlegame.f2s.com - my 2D Platformer. Version 3 available since Feb' 02 !

Edited by - cmdkeen on February 23, 2002 9:58:44 AM

Edited by - cmdkeen on February 23, 2002 9:59:30 AM

Share this post


Link to post
Share on other sites
Fruny,
that was just an example ... I have many functions that I am going to put in the class too. But, I still cant get the class to work. It is because when I include the header file into any of my projects it things that either: 1) I using Math without it being declared, or 2) I declaring multiple instances of Math. Anyone ever have these problems?

Share this post


Link to post
Share on other sites
cmdkeen: Alexandrescu "Modern C++ Design" 6.10 p148, implemented there (choose "Source Code"). Unfortunately, as VC++ is broken, you can't use the Loki library with it (including VC.NET). The author uses CodeWarrior.

or, shortly

    
// Singleton header file


template<class T>
class Singleton
{
static T* instance;
Singleton();
public:
static T& Instance();
}

// In _one_ of your source files


MyClass* Singleton<MyClass>::instance = NULL;


You don't declare a generic template instance pointer.

Edited by - Fruny on February 23, 2002 7:13:13 PM

Share this post


Link to post
Share on other sites
quote:
Original post by jag_oes
when I include the header file into any of my projects it things that either: 1) I using Math without it being declared, or 2) I declaring multiple instances of Math. Anyone ever have these problems?


I assume your header files have include guards : either portably
  
// MyHeader.h

#ifndef MYHEADER_H
#define MYHEADER_H

// My header goes here


#endif MYHEADER_H

or MSVCly (anything in #pragma is by definition compiler-dependant : if a compiler doesn''t implement a given pragma, it will just ignore it.)
  
#pragma once

// My header goes here




One thing you have to remember though is that you cannot create that Math variable. That''s the whole point of having a Singleton pattern : you can only have one variable of that type, and can only access it through the GetInstance() function.

As I said before, you may create a reference to the singleton. However, remember that at link time you can only have one symbol with a given name. Which means that if you declare a MathSingleton reference in both FileA.cpp and FileB.cpp, the linker will scream.

There are several ways to solve that problem :
- declare in the header, define in a source file.
  
// MathSingleton.h


extern MathSingleton& Math; // just a declaration (extern)


// MathSingleton.cpp


MathSingleton& Math& = MathSingleton::GetInstance(); // actual definition.



- Declare your references locally, either using unnamed namespaces (C++ style)
  
// FileA.cpp


namespace
{
MathSingleton& Math = MathSingleton::GetInstance();
}
...
Math.foo();

// FileB.cpp


namespace
{
MathSingleton& Math = MathSingleton::GetInstance();
}
...
Math.bar(); // not the same ''Math'' symbol as in FileA.cpp


or the static keyword (C style)
  
// FileA.cpp


static MathSingleton& Math = MathSingleton::GetInstance();
...
Math.foo();

// FileB.cpp


static MathSingleton& Math = MathSingleton::GetInstance();
...
Math.bar(); // idem



Share this post


Link to post
Share on other sites

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!