what's wrong with the following singleton class???

Y

ying.gary.zhang

// T.h:

class T
{
public:
static T* instance();
private:
T() {}
~T() {}
static T* smInstance;
};

// T.cpp:

T* T::instance()
{
if (smInstance == NULL)
smInstance = new T();

return smInstance;
}

when I try to compile the above code, there is linker error:
.../T.cpp:3: undefined reference to `T::smInstance`

I am using gcc 3.4.6 under gentoo linux, thanks
 
A

Alf P. Steinbach

* (e-mail address removed):
// T.h:

class T
{
public:
static T* instance();
private:
T() {}
~T() {}
static T* smInstance;
};

// T.cpp:

T* T::instance()
{
if (smInstance == NULL)
smInstance = new T();

return smInstance;
}

when I try to compile the above code, there is linker error:
../T.cpp:3: undefined reference to `T::smInstance`

I am using gcc 3.4.6 under gentoo linux, thanks

You have declared but not defined 'smInstance'.

It should be defined in your [T.cpp] file.

But instead, just do

class T
{
private:
T() {}
T( T const& );
~T() {}
public:
static T& instance()
{
T theInstance;
return theInstance;
}
};
 
A

Alf P. Steinbach

* Alf P. Steinbach:
* (e-mail address removed):
// T.h:

class T
{
public:
static T* instance();
private:
T() {}
~T() {}
static T* smInstance;
};

// T.cpp:

T* T::instance()
{
if (smInstance == NULL)
smInstance = new T();

return smInstance;
}

when I try to compile the above code, there is linker error:
../T.cpp:3: undefined reference to `T::smInstance`

I am using gcc 3.4.6 under gentoo linux, thanks

You have declared but not defined 'smInstance'.

It should be defined in your [T.cpp] file.

But instead, just do

class T
{
private:
T() {}
T( T const& );
~T() {}
public:
static T& instance()
{
T theInstance;

Should be

static T theInstance;

of course.
 
Y

ying.gary.zhang

if the class is used in multi-threaded environment, will there be any
problem ????
 
A

Alf P. Steinbach

* (e-mail address removed):
if the class is used in multi-threaded environment, will there be any
problem ????

Please quote what you're responding to.
 
?

???

When you declare a static member, you should define it in the
implementation.

// T.h:

class T
{
public:
static T* instance();
private:
T() {}
~T() {}
static T* smInstance;

you declared smInstance here (in .h file)


but in the implementatin file, (.cpp file), you don't define it (initialize
it). just do like this:

static T::smInstance = NULL;
 
N

Noah Roberts

if the class is used in multi-threaded environment, will there be any
problem ????

Depends on what the singleton does. You always have to lock certain
resources to avoid race conditions and other bugbears.
_Generic_Programming_ has some information you might be interested in.
 
A

Aman Angrish

if the class is used in multi-threaded environment, will there be any
problem ????

yes there would be.
You need to mutex protect access to the critical sections. In this case,
your instance() function should use the "Double checked locking pattern"
for "creation" of the instance.

regards,
Aman Angrish.
 
E

Earl Purple

Aman said:
yes there would be.
You need to mutex protect access to the critical sections. In this case,
your instance() function should use the "Double checked locking pattern"
for "creation" of the instance.

regards,
Aman Angrish.

You only need to do that when it's implemented as a pointer. When it is
implemented as an instance within a function then technically there
should be no race conditions, atlhough you then rely on whether
compilers are compliant enough to implement it that way. Of course, you
can avoid that problem also by ensuring the instance is created before
you create mulitple threads that access it.

Generally I simply don't use singletons. Abandoned them a year or so
ago and never had any real problems.
 
W

werasm

Earl said:
Generally I simply don't use singletons. Abandoned them a year or so
ago and never had any real problems.

I hear a bell ringing somewhere that singletons are handy for creation
on demand. Something will only be created when required. That said,
singletons open a whole can of worms of its own and one has to read
about 5 books to realize all its subtleties.

If single controlled access to a unique instance, and not "creation on
demand" is the reason for the singleton, I prefer this slight variation
on the singleton:

class Singleton
{
public:
static void create( /*params*/ );
static void destroy();
static Singleton* instance();
//...
};

This seperates responsibilities quite nicely. Create is typically
called only once in the application - right at the beginning. If this
is not the case, instance() throws during first access. Destroy need
never be called, or after the last time Singleton is referenced.
Another idea would be to return a weak_ptr, the instance itself being
the only shared_ptr - destroyed automatically when application ends,
and all references (weak_ptrs) to it invalidated).

Regards,

W
 
E

Earl Purple

werasm said:
If single controlled access to a unique instance, and not "creation on
demand" is the reason for the singleton,
From what I see of the use of singletons, the convenience is being able
to use it without having to pass the reference to it through the class
header, thus supposedly hiding the implementation detail.

I circumvent this by using either the pImpl paradigm or having an
abstract base class and a factory, so users of your class (or its
abstact base) do not need to see how you implement.

With a lot of singletons I come across, although there is only one
instance, there is no particular reason why there couldn't be more than
one - for example a database. Why shouldn't an application interact
with more than one database?

Having an "open the first time on use" does not imply singleton, it
implies an equivalent to lazy-evaluation.

How to handle the re-entrant and mulitple-creation situation is down to
the specifics of the application. If you want multiple connections to a
database each running in different threads, then the best option is to
open the database first just before you create a connection pool. You
ensure this by designing your classes well.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,754
Messages
2,569,521
Members
44,995
Latest member
PinupduzSap

Latest Threads

Top