• 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 5787 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
Why would you need a global maths object for a maths library? How and what is the benefit of an object of class "Maths"?

Share this post


Link to post
Share on other sites
Use a namespace Math instead of an object.
You can put static const float/double/int in the namespace and functions as well. I've seen a few libraries with a static xxMath object, but they are out-moded by the addition of namespaces.

There's about a dozen different flavors of singletons. As-always, which one you want depends on what you are trying to accomplish.

Edited by - Magmai Kai Holmlor on March 3, 2002 11:01:10 PM

Share this post


Link to post
Share on other sites
Also it''s useful to implement a singleton destroyer companion class. This makes sure you''re singleton object is deleted.

it''s basically a static object with a pointer to the singleton class, that''s deleted in the destructor.
I had some example code but I can''t find it and I don''t really have time to type it out again.

"That''s not a bug, it''s a feature!"
--me

Share this post


Link to post
Share on other sites
or you can just make your singleton instance static, so it cleans itself up... which is what I generally do because I can''t be arsed having another class which exists for the sole purpose of cleaning up another.

ie
  
class Singleton
{
private:
Singleton();

public:
static Singleton& GetInstance()
{
static Singleton m_instance;
return m_instance;
}
...
};


i hope i remembered that correctly ... the advantage here is that it is only instantiated on the first call to GetInstance, and it cleans itself up, so no mucking about with determining who deletes it... its all good

Share this post


Link to post
Share on other sites
The disadvantage is that the order of static object construction is undefined (technically it''s spurious). So a static implementation of a singleton will work so long as no other static singelton depends on it being constructed during it''s construction.

As convoluted as that sounds, it''s not a terribly uncommon snafu.

Share this post


Link to post
Share on other sites
quote:
Original post by Magmai Kai Holmlor
The disadvantage is that the order of static object construction is undefined (technically it''s spurious). So a static implementation of a singleton will work so long as no other static singelton depends on it being constructed during it''s construction.

As convoluted as that sounds, it''s not a terribly uncommon snafu.


Ahh, but you are missing the point here.
Global static variable instansiation order is undefined, but static variables inside functions are instantiated the first time the function is called, hence there is no problem with BadMonkeys code.

Share this post


Link to post
Share on other sites
quote:
Original post by Void
Why would you need a global maths object for a maths library? How and what is the benefit of an object of class "Maths"?

Original post by Magmai Kai Holmlor
Use a namespace Math instead of an object.
You can put static const float/double/int in the namespace and functions as well. I''ve seen a few libraries with a static xxMath object, but they are out-moded by the addition of namespaces.


Its useful when you have several optimized math libraries (MMX, SSE, SSE2, 3DNow, etc) and you want to instantiate the most appropriate one for the processor you are running on. Namespaces cant do this for you. You could do it using function pointers, but you can say the same thing about anything OO. Using a Math class with an accessor method that ensures the correct type is constructed is just more elegant.

Share this post


Link to post
Share on other sites
Personally, I prefer to leave the constructor public and reference count the object. This makes using the object a little easier to use (at least I think so):

  

class singleton
{
public:

// I don''t make my member functions static since none are virtual.


singleton()
{
if (refcount < 1)
{
// Aquire resources here

}

refcount++;
}

//members here...


~singleton()
{
refcount--;

if (refcount > 0)
{
// Release resources here

}
}

private:

static int refcount;
// All other member variables declared static

};



Make sure in the cpp file you initialize refcount to zero:

int singleton::refcount = 0;

And use it like any other class. The first "instance" you create will initialize the object and the last to go will un-initialize it.

I''d create this as a stack based object but I can''t think of a reason why such an object couldn''t be created dynamically (just make sure you match your new''s with delete''s).

Share this post


Link to post
Share on other sites
um... Solo... i may be missing something, but this is not a singleton (as I understand it). The singleton pattern is based on the idea that only one instance of the object is ever instantiated . In a singelton pattern, the constructor is private for the very reason that you must not explicitly call it.

Using your approach, it seems you can instantiate as many of these objects as you like... and only the objects created when the static refcount == 0 ever aquire resources (and are not guaranteed to release them if your instantiate more than one)... the rest will be dangling out there with no handles to anything as far as I can see. It also seems that if your objects are to share the resources, all state must be static, in which case you may as well access them directly, rather than through an object... they are effectively a set of global variables!

Share this post


Link to post
Share on other sites
quote:
Original post by Magmai Kai Holmlor
The disadvantage is that the order of static object construction is undefined (technically it''s spurious


The creation order is well defined (when the function gets called).

It''s the destruction order that is undefined using this "Meyer''s singleton".

Yes, there are situations where singletons depend on singletons. For eg. I have a logger singleton utility used for tracing which may be called by singleton''s ctor/dtor .

Share this post


Link to post
Share on other sites
quote:
Void
The creation order is well defined (when the function gets called).

It''s the destruction order that is undefined using this "Meyer''s singleton".


Too many statics I was thinking of static objects'' construction, not static properties'' construction.


...could you implement a singleton by overloading new for the class? Is there a way to prevent a stack instance without making the ctor or dtor protected or private?


quote:

Its useful when you have several optimized math libraries (MMX, SSE, SSE2, 3DNow, etc) and you want to instantiate the most appropriate one for the processor you are running on.


Hadn''t thought of that...

I don''t think I''d make such a class a singleton though. If there''s state information it wouldn''t be thread-friendly as a singleton, and if you build any tables they could be static properties anyway.

I think I would go by processor...

IMath
o
|
CPentiumMMX
|
+--CPentiumII
| |
| +--CPentiumIII
| |
| +--CPentium4
|
+--CK63
|
+--CAthlon
|
+--CAthlonXP


And then the pattern of choice is a factory to build the appro. concrete class.

Share this post


Link to post
Share on other sites
quote:
Original post by Magmai Kai Holmlor
...could you implement a singleton by overloading new for the class? Is there a way to prevent a stack instance without making the ctor or dtor protected or private?



The only(?) and easiest way to prevent a stack variable is to hide the dtor.

Yes, I suppose you could overload new for implementing singleton. The new operator keeps track of a ref count.

But the point is you have to do this for every class you want to make into a singleton. This is tedious. What I have (and Modern C++ Design shows) is a reusable singleton pattern container. So to turn a class into a singleton, all we do is


typedef singleton_holder MyClassSingleton;


And we access MyClassSingleton from there onwards. No need to remember the gritty details of singleton as such


Edited by - void on March 8, 2002 2:06:14 AM

Share this post


Link to post
Share on other sites
quote:
Original post by Bad Monkey
um... Solo... i may be missing something, but this is not a singleton (as I understand it). The singleton pattern is based on the idea that only one instance of the object is ever instantiated . In a singelton pattern, the constructor is private for the very reason that you must not explicitly call it.

Using your approach, it seems you can instantiate as many of these objects as you like... and only the objects created when the static refcount == 0 ever aquire resources (and are not guaranteed to release them if your instantiate more than one)... the rest will be dangling out there with no handles to anything as far as I can see. It also seems that if your objects are to share the resources, all state must be static, in which case you may as well access them directly, rather than through an object... they are effectively a set of global variables!



Since all data members are static only one instance of them ever exists. Create as many ''instances'' of the class as you like, they will all point to the same data and therefore have the same state (singleton). The reference count simply makes sure that the data/resources are aquired (if they haven''t already been aquired) and are not released while a "pointer" (used for lack of a better word) to the data still exists. Putting the data into a class has the advantage of allowing you to better organize your data and protect it using access specifiers.

Share this post


Link to post
Share on other sites
yes Solo, I understand the approach you have taken... it just seems a very roundabout/unusual way to implement the pattern... I certainly haven''t seen it before.

I think what confused me (besides my tiredness when i posted) was perhaps a typo in the destructor code (maybe the condition of releasing resources should be "refcount < 1"?).

Now that I have taken a better look (and gotten some sleep ), your method does hold some merit, in that you can simply declare a variable of that type and use the singleton transparently, rather than the usual declare pointer/reference and obtain handle from static member function. In effect, the "object" you declare will simply consist of a this pointer.

The downside may be if a user of the class forgets this is a singleton and tries something silly e.g. declares a variable of this type with the intent of using as a temp or transient object, filling it with garbage and/or tampering with state. Contrived, I know, as candidates for being a singleton probably wouldn''t see this kind of usage, but a danger nevertheless. Explicit pointers/references make the user more mindful of making such changes I guess...

Share this post


Link to post
Share on other sites
quote:
Original post by Bad Monkey
The downside may be if a user of the class forgets this is a singleton and tries something silly e.g. declares a variable of this type with the intent of using as a temp or transient object, filling it with garbage and/or tampering with state.


Yeah, It''s one of the draw backs of the approach. I like it because I feel that the ability to derive classes from the singleton out weigh the disadvantages.

Sorry about the typo. You were right - It should have read "refcount < 1".

Share this post


Link to post
Share on other sites

  • Advertisement