By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
457,727 Members | 1,263 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 457,727 IT Pros & Developers. It's quick & easy.

Singleton usage

P: n/a
Consider the classic singleton (from Thinking in C++):
-----------------------------------------------------
//: C10:SingletonPattern.cpp
#include <iostream>
using namespace std;

class Singleton {
static Singleton s;
int i;
Singleton(int x) : i(x) { }
Singleton& operator=(Singleton&); // Disallowed
Singleton(const Singleton&); // Disallowed
public:
static Singleton& instance() { return s; }
int getValue() { return i; }
void setValue(int x) { i = x; }
};
-----------------------------------------------------

I've read this type of singleton is often used to store the global
variables, but I don't have found a clear explanation.

An example:

if, in file main.cpp, I write

Singleton Singleton::s(47);
Singleton& s = Singleton::instance();

and, in foo1.cpp, I write

Singleton& s1 = Singleton::instance();

and in foo2.cpp I write

Singleton& s2 = Singleton::instance();
these instances (s, s1 and s2) are the same object, so all methods and
properties are shared???? Because Singleton::s is static, I suppose yes,
but I'm not sure...

thx,

Manuel

Jan 7 '06 #1
Share this Question
Share on Google+
6 Replies


P: n/a
Manuel wrote:
Consider the classic singleton (from Thinking in C++):
-----------------------------------------------------
//: C10:SingletonPattern.cpp
#include <iostream>
using namespace std;

class Singleton {
static Singleton s;
int i;
Singleton(int x) : i(x) { }
Singleton& operator=(Singleton&); // Disallowed
Singleton(const Singleton&); // Disallowed
public:
static Singleton& instance() { return s; }
int getValue() { return i; }
void setValue(int x) { i = x; }
};
-----------------------------------------------------

I've read this type of singleton is often used to store the global
variables, but I don't have found a clear explanation.

An example:

if, in file main.cpp, I write

Singleton Singleton::s(47);
Singleton& s = Singleton::instance();

and, in foo1.cpp, I write

Singleton& s1 = Singleton::instance();

and in foo2.cpp I write

Singleton& s2 = Singleton::instance();
these instances (s, s1 and s2) are the same object,
They are all _references_, and they do _refer_ to the same object, yes.
so all methods and
properties are shared????
Since they _refer_ to the same object, all "properties" are that of the
object to which they refer.
Because Singleton::s is static, I suppose
yes, but I'm not sure...


Yes. The implementation makes sure that (a) only one instance of that
class can ever be created in the program and (b) any time somebody wants
to use it, they are forced to use a _reference_ to that instance. That
is essentially the definition of a singleton.

V
Jan 7 '06 #2

P: n/a
Victor Bazarov wrote:
Yes. The implementation makes sure that (a) only one instance of that
class can ever be created in the program and (b) any time somebody wants
to use it, they are forced to use a _reference_ to that instance. That
is essentially the definition of a singleton.


Thank you very much!

Manuel
Jan 7 '06 #3

P: n/a
Victor Bazarov wrote:
Yes. The implementation makes sure that [...]

Another question.
The example in "Thinking in C++" is:
----------------------------------------
Singleton Singleton::s(47);

int main() {
Singleton& s = Singleton::instance();
cout << s.getValue() << endl;
Singleton& s2 = Singleton::instance();
s2.setValue(9);
cout << s.getValue() << endl;
} ///:~
----------------------------------------

Any particular reason the singleton init is out of main()?
It should be global even if declared into a function, right?

thx,

Manuel

Jan 7 '06 #4

P: n/a
Manuel wrote:
Victor Bazarov wrote:
Yes. The implementation makes sure that [...]

Another question.
The example in "Thinking in C++" is:
----------------------------------------
Singleton Singleton::s(47);

int main() {
Singleton& s = Singleton::instance();
cout << s.getValue() << endl;
Singleton& s2 = Singleton::instance();
s2.setValue(9);
cout << s.getValue() << endl;
} ///:~
----------------------------------------

Any particular reason the singleton init is out of main()?
It should be global even if declared into a function, right?


That's the requirement for static data members of any class.
If they are to be defined, they must be defined at the namespace
scope.

V
Jan 8 '06 #5

P: n/a

Manuel wrote:
Victor Bazarov wrote:
Yes. The implementation makes sure that [...]

Another question.
The example in "Thinking in C++" is:
----------------------------------------
Singleton Singleton::s(47);

int main() {
Singleton& s = Singleton::instance();
cout << s.getValue() << endl;
Singleton& s2 = Singleton::instance();
s2.setValue(9);
cout << s.getValue() << endl;
} ///:~
----------------------------------------

Any particular reason the singleton init is out of main()?
It should be global even if declared into a function, right?


Since s is a static inside of Singleton it has to be initialized. All
static variables must be initialized exactly once or you will get a
linker error (because the declaration is just that and the variable was
never defined).

Try it and see...

Jan 9 '06 #6

P: n/a
Manuel wrote:
Consider the classic singleton (from Thinking in C++):
-----------------------------------------------------
//: C10:SingletonPattern.cpp
#include <iostream>
using namespace std;

class Singleton {
static Singleton s;
int i;
Singleton(int x) : i(x) { }
Singleton& operator=(Singleton&); // Disallowed
Singleton(const Singleton&); // Disallowed
public:
static Singleton& instance() { return s; }
int getValue() { return i; }
void setValue(int x) { i = x; }
};
-----------------------------------------------------

I've read this type of singleton is often used to store the global
variables, but I don't have found a clear explanation.


Be aware, that if the above singleton is called from another global
object during initialization that's in a different translation unit,
than it can, and most likely will fail.

There's no garantee for the order of initialization of global complex
objects located in different translation units.
See following links:
http://www.informit.com/guides/conte...eqNum=212&rl=1

And read SECOND paragraph in the following link:
http://www.codeguru.com/cpp/tic/tic0114.shtml
A safer method would be the following:
class Singleton {
static const int m_MySingletonParam;
int i;
Singleton(int x) : i(x) { }
Singleton& operator=(Singleton&); // Disallowed
Singleton(const Singleton&); // Disallowed
public:
static Singleton& instance()
{
static Singleton s(m_MySingletonParam);
return s;
}
int getValue() { return i; }
void setValue(int x) { i = x; }
};

//In one CPP file
const int Singleton::m_MySingletonParam = 123;
The above method is garanteed to work, because POD types are garanteed
to be initailized before non-POD types. And local static variables are
garanteed to be initialized when the function is called.
So you can safely call the above Singleton from any other global
object's constructor, regardless of the translation unit.

If it's possible that the singlton will be called after main() exits,
then you should create the object via new, to make sure it doesn't get
destroyed before othe global object's destructs are called.
static Singleton& instance()
{
static Singleton *s = new Singleton (m_MySingletonParam);
return *s;
}

Jan 9 '06 #7

This discussion thread is closed

Replies have been disabled for this discussion.