Microsoft Interview Question
Software Engineer / DevelopersTeam: Global Foundation Services
Country: United States
Interview Type: In-Person
Just use non-lazy load version:
class MyClass
{
private static MyClass _instance = new MyClass();
public MyClass GetInstance() {return _instance;}
}
The MyClass constructor should also be declared private for this class to be truly a singleton
The MyClass constructor should also be declared private for this class to be truly a singleton
The MyClass constructor should also be declared private for this class to be truly a singleton
#ifndef SINGLETON_HPP
#define SINGLETON_HPP
#ifdef __GNUC__
#define HAS_THREAD_SAFE_STATICS 1
#endif
#if defined _MSC_VER
#include <intrin.h>
inline void MemoryWriteBarrier() { _WriteBarrier(); }
#elif __GNUC__
#if defined __i386__ || defined __x86_64__
inline void MemoryWriteBarrier() { __asm__ __volatile__("sfence" ::: "memory");
}
#else
#endif
#ifdef HAS_THREAD_SAFE_STATICS
template <class T>
class SingletonBase
{
private:
SingletonBase(const SingletonBase&);
void operator=(const SingletonBase&);
protected:
SingletonBase() {}
~SingletonBase() {}
public:
static T& Instance()
{
static T instance;
return instance;
}
};
#else
template <typename T>
class SingletonBase
{
private:
SingletonBase(const SingletonBase&);
void operator=(const SingletonBase&);
protected:
SingletonBase() {}
~SingletonBase() {}
public:
static T& Instance()
{
if (!m_instance)
{
ScopedLocker<Mutex> lock(m_lock);
if (!m_instance)
{
T* p = new T();
MemoryWriteBarrier();
m_instance = p;
atexit(Destroy);
}
}
return *m_instance;
}
private:
static void Destroy()
{
if (m_instance)
{
delete m_instance;
m_instance = NULL;
}
}
private:
static Mutex m_lock;
static T* volatile m_instance;
};
template <typename T>
Mutex SingletonBase<T>::m_lock;
template <typename T>
T* volatile SingletonBase<T>::m_instance;
#endif // HAS_THREAD_SAFE_STATICS
template <typename T>
class Singleton : public SingletonBase<T>
{
};
#endif // SINGLETON_HPP
Class Singleton{
int a;
int b;
...
}Singleton;
Use Singleton as object where ever you want to use, it will not all you to create a object as Singletion obj; as Singleton itself is an object. It also allows static vars like Singleton::a. Not sure if there any new compilers not supporting this, but I tested this in spro 3.4.
class Singleton{
private static Singleton instance;
private Singleton(){
}
public static Singleton getInstance(){
if(Singleton.instance == null){
Singleton.instance = new Singleton();
}
return (Singleton.instance == null)? (Singleton.instance = new Singleton()) : Singleton.instance;
}
}
Double-checked locking can actually be incorrect, and is thus often considered an anti-pattern. Find the article on it on Wikipedia.
- eugene.yarovoi January 09, 2012