• Advertisement

Archived

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

I do not know how to implement a Singleton Class

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