Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > singleton question

Reply
Thread Tools

singleton question

 
 
kathy
Guest
Posts: n/a
 
      02-24-2011
I try to implement the Singleton for my Driver. The code piece:

/////////////////////////
MySingleton.h
/////////////////////////
template <class T> class CSingleton
{
public:
static T* GetInstance();

protected:
CSingleton();
~CSingleton();

private:
CSingleton(CSingleton const&);
CSingleton& operator=(CSingleton const&);
static T* m_pInstance;
};

/////////////////////////
MySingleton.cpp
/////////////////////////

#include "StdAfx.h"
#include "MySingleton.h"

template <class T> T* CSingleton<T>::m_pInstance=NULL;
template <class T> T* CSingleton<T>::GetInstance()
{
if(!m_pInstance)
m_pInstance = new T;

assert(m_pInstance !=NULL);

return m_pInstance;
}

/////////////////////////
Driver.h
/////////////////////////

class CDriver
{
public:
CDriver(void);
~CDriver(void);

int GetData();

private:
int m_nData;
};

/////////////////////////
Driver.cpp
/////////////////////////

#include "StdAfx.h"
#include "Driver.h"


CDriver::CDriver(void):
m_nData(100)
{
}


CDriver::~CDriver(void)
{
}

int CDriver::GetData()
{
return m_nData;
}

In my MFC dialog button routine:

void CMyDlg::OnBnClickedButtonSingleton()
{
int n = 1;
CDriver *pDriver = CSingleton<CDriver>::GetInstance();
n = pDriver->GetData();
}

When I try to build it in studio 2010, I got link error:

MyDlg.obj : error LNK2019: unresolved external symbol "public: static
class CDriver * __cdecl CSingleton<class
CDriver>::GetInstance(void)" (?GetInstance@?
$CSingleton@VCDriver@@@@SAPAVCDriver@@XZ) referenced in function
"public: void __thiscall
CBoostDlg::OnBnClickedButtonSingleton(void)" (?
OnBnClickedButtonSingleton@CBoostDlg@@QAEXXZ)
C:\Temp\Studio 2010\TestDlg\Debug\Test.exe : fatal error LNK1120: 1
unresolved externals

What is wrong?

 
Reply With Quote
 
 
 
 
kathy
Guest
Posts: n/a
 
      02-24-2011
On Feb 24, 9:45*am, Leigh Johnston <le...@i42.co.uk> wrote:
> On 24/02/2011 15:23, kathy wrote:
>
>
>
>
>
> > I try to implement the Singleton for my Driver. The code piece:

>
> > /////////////////////////
> > MySingleton.h
> > /////////////////////////
> > template<class T> *class CSingleton
> > {
> > public:
> > * *static T* GetInstance();

>
> > protected:
> > * *CSingleton();
> > * *~CSingleton();

>
> > private:
> > * *CSingleton(CSingleton const&);
> > * *CSingleton& *operator=(CSingleton const&);
> > * *static T* m_pInstance;
> > };

>
> > /////////////////////////
> > MySingleton.cpp
> > /////////////////////////

>
> > #include "StdAfx.h"
> > #include "MySingleton.h"

>
> > template<class T> *T* CSingleton<T>::m_pInstance=NULL;
> > template<class T> *T* CSingleton<T>::GetInstance()
> > {
> > * *if(!m_pInstance)
> > * *m_pInstance = new T;

>
> > * *assert(m_pInstance !=NULL);

>
> > * *return m_pInstance;
> > }

>
> > /////////////////////////
> > Driver.h
> > /////////////////////////

>
> > class CDriver
> > {
> > public:
> > * *CDriver(void);
> > * *~CDriver(void);

>
> > * *int GetData();

>
> > private:
> > * *int m_nData;
> > };

>
> > /////////////////////////
> > Driver.cpp
> > /////////////////////////

>
> > #include "StdAfx.h"
> > #include "Driver.h"

>
> > CDriver::CDriver(void):
> > * *m_nData(100)
> > {
> > }

>
> > CDriver::~CDriver(void)
> > {
> > }

>
> > int CDriver::GetData()
> > {
> > * *return m_nData;
> > }

>
> > In my MFC dialog button routine:

>
> > void CMyDlg::OnBnClickedButtonSingleton()
> > {
> > * *int n = 1;
> > * *CDriver *pDriver = CSingleton<CDriver>::GetInstance();
> > * *n = pDriver->GetData();
> > }

>
> > When I try to build it in studio 2010, I got link error:

>
> > MyDlg.obj : error LNK2019: unresolved external symbol "public: static
> > class CDriver * __cdecl CSingleton<class
> > CDriver>::GetInstance(void)" (?GetInstance@?
> > $CSingleton@VCDriver@@@@SAPAVCDriver@@XZ) referenced in function
> > "public: void __thiscall
> > CBoostDlg::OnBnClickedButtonSingleton(void)" (?
> > OnBnClickedButtonSingleton@CBoostDlg@@QAEXXZ)
> > C:\Temp\Studio 2010\TestDlg\Debug\Test.exe : fatal error LNK1120: 1
> > unresolved externals

>
> > What is wrong?

>
> Move the code in MySingleton.cpp into MySingleton.h and delete
> MySingleton.cpp that should fix it.
>
> By having template code in a different TU you are not instantiating it.
>
> /Leigh- Hide quoted text -
>
> - Show quoted text -


Thank you. I forgot it
 
Reply With Quote
 
 
 
 
Victor Bogado
Guest
Posts: n/a
 
      03-02-2011
On Feb 24, 12:23*pm, kathy <yqin...@yahoo.com> wrote:
> ...
>
> template <class T> T* CSingleton<T>::m_pInstance=NULL;
> template <class T> T* CSingleton<T>::GetInstance()
> {
> * if(!m_pInstance)
> * * * * m_pInstance = new T;


Also This is not thread safe, you could have a race condition that
would end up with 2 instances. The best solution is to use the
instance as a static local in the instance method. The standard says
that it will be instantiated before the first call.

> ...

 
Reply With Quote
 
Victor Bogado
Guest
Posts: n/a
 
      03-02-2011
On Mar 2, 12:31*pm, Leigh Johnston <le...@i42.co.uk> wrote:
> On 02/03/2011 15:25, Victor Bogado wrote:
>
> > On Feb 24, 12:23 pm, kathy<yqin...@yahoo.com> *wrote:
> >> ...

>
> >> template<class T> *T* CSingleton<T>::m_pInstance=NULL;
> >> template<class T> *T* CSingleton<T>::GetInstance()
> >> {
> >> * *if(!m_pInstance)
> >> * * * * *m_pInstance = new T;

>
> > Also This is not thread safe, you could have a race condition that
> > would end up with 2 instances. The best solution is to use the
> > instance as a static local in the instance method. The standard says
> > that it will be instantiated before the first call.

>
> No; such a static will be instantiated *during* the first call however
> you still have a race condition with a local static in a multi-threaded
> situation.
>
> /Leigh


This would have a race condition? I was under the impression that the
instantiation in that case would be atomic, but I never read the
standard myself, so I could be wrong .

static SingletonType& SingletonType::instance()
{
SingletonType instance;

return instance;
}
 
Reply With Quote
 
Victor Bogado
Guest
Posts: n/a
 
      03-02-2011
On Mar 2, 2:28*pm, Victor Bogado <bog...@gmail.com> wrote:
> On Mar 2, 12:31*pm, Leigh Johnston <le...@i42.co.uk> wrote:
>
>
>
>
>
>
>
>
>
> > On 02/03/2011 15:25, Victor Bogado wrote:

>
> > > On Feb 24, 12:23 pm, kathy<yqin...@yahoo.com> *wrote:
> > >> ...

>
> > >> template<class T> *T* CSingleton<T>::m_pInstance=NULL;
> > >> template<class T> *T* CSingleton<T>::GetInstance()
> > >> {
> > >> * *if(!m_pInstance)
> > >> * * * * *m_pInstance = new T;

>
> > > Also This is not thread safe, you could have a race condition that
> > > would end up with 2 instances. The best solution is to use the
> > > instance as a static local in the instance method. The standard says
> > > that it will be instantiated before the first call.

>
> > No; such a static will be instantiated *during* the first call however
> > you still have a race condition with a local static in a multi-threaded
> > situation.

>
> > /Leigh

>
> This would have a race condition? I was under the impression that the
> instantiation in that case would be atomic, but I never read the
> standard myself, so I could be wrong .
>


the code should be :

static SingletonType& SingletonType::instance()
{
* * static SingletonType instance;
* * return instance;
}


 
Reply With Quote
 
James Kanze
Guest
Posts: n/a
 
      03-02-2011
On Mar 2, 5:34 pm, Leigh Johnston <le...@i42.co.uk> wrote:
> On 02/03/2011 17:33, Victor Bogado wrote:
> > On Mar 2, 2:28 pm, Victor Bogado<bog...@gmail.com> wrote:
> >> On Mar 2, 12:31 pm, Leigh Johnston<le...@i42.co.uk> wrote:


> >>> On 02/03/2011 15:25, Victor Bogado wrote:


> >>>> On Feb 24, 12:23 pm, kathy<yqin...@yahoo.com> wrote:
> >>>>> ...


> >>>>> template<class T> T* CSingleton<T>::m_pInstance=NULL;
> >>>>> template<class T> T* CSingleton<T>::GetInstance()
> >>>>> {
> >>>>> if(!m_pInstance)
> >>>>> m_pInstance = new T;


> >>>> Also This is not thread safe, you could have a race condition that
> >>>> would end up with 2 instances. The best solution is to use the
> >>>> instance as a static local in the instance method. The standard says
> >>>> that it will be instantiated before the first call.


> >>> No; such a static will be instantiated *during* the first call however
> >>> you still have a race condition with a local static in a multi-threaded
> >>> situation.


> >> This would have a race condition? I was under the impression that the
> >> instantiation in that case would be atomic, but I never read the
> >> standard myself, so I could be wrong .


> > the code should be :


> > static SingletonType& SingletonType::instance()
> > {
> > static SingletonType instance;
> > return instance;
> > }


> >


> Not thread-safe.


That depends. According to the draft C++0x: "If control enters
the declaration [of a local static variable] concurrently while
the object variable is being initialized, the concurrent
execution shall wait for completion of the initialization." Pre
C++0x, anything involving threads was defined by the
implementation (undefined behavior according to the standard,
but an implementation is free to define undefined behavior, and
both Posix and Windows do). In this case, g++ has always
behaved as C++0x will require, or at least, it has officially
guaranteed it did, since the first version which supported
threading at all (3.0).

--
James Kanze
 
Reply With Quote
 
Andy Venikov
Guest
Posts: n/a
 
      03-03-2011
On 03/02/2011 02:21 PM, James Kanze wrote:
<snip>

>
>> Not thread-safe.

>
> That depends. According to the draft C++0x: "If control enters
> the declaration [of a local static variable] concurrently while
> the object variable is being initialized, the concurrent
> execution shall wait for completion of the initialization." Pre
> C++0x, anything involving threads was defined by the
> implementation (undefined behavior according to the standard,
> but an implementation is free to define undefined behavior, and
> both Posix and Windows do). In this case, g++ has always
> behaved as C++0x will require, or at least, it has officially
> guaranteed it did, since the first version which supported
> threading at all (3.0).


Actually, thread-safe locals were introduced in 3.4. (They may have been
back-patched to earlier versions, but they did not exist in the originals).

But it looks like prior to 4.0 the logic was broken for non-POD types
since the constructor would be called while holding a global lock and if
the constructor contained another local static or was calling a function
that contained a global static, the program would dead-lock since the
global lock was not re-entrant.

MSVC never tried to make static locals thread-safe. That is, prior to C++0x


>
> --
> James Kanze


Andy.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Singleton methods without the singleton class Charles Oliver Nutter Ruby 4 03-22-2010 10:46 PM
Singleton object vs. enhancing singleton class Paul McMahon Ruby 3 06-09-2008 06:05 AM
Singleton Modules rather than Singleton Classes Trans Ruby 12 09-14-2007 06:45 AM
Singleton - Whether Cloneable overrides Singleton Proton Projects - Moin Java 4 03-27-2007 02:59 AM
Singleton classes and Singleton pattern Wilhelm Ruby 1 10-11-2006 01:08 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57