例模式可以保证系统中只有一个类只有一个实例,并提供一个访问它的全局访问点,该实例被所有程序模块共享。
单例模式的要点有三个:
1. 单例类只能有一个实例
2. 它必须自行创建这个实例
3. 它必须自行向整个系统提供提供这个实例。
单线程的工厂模式:
饿汉模式
singleton.h
#ifndef _SINGLETON_H_
#define _SINGLETON_H_
#include <cstdio>
class Singleton
{
public:
static Singleton* getInstance();
int getValue();
void setValue(int new_value);
virtual ~Singleton();
private:
Singleton();
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
int int_a;
static Singleton* instance;
/*This class is only used for garbage collection*/
class Garbo
{
public:
~Garbo()
{
if(Singleton::instance!=nullptr)
{
printf("%s\n",__func__);
delete Singleton::instance;
Singleton::instance=nullptr;
}
}
};
static Garbo _garbo;
};
#endif
singleton.cpp
#include "singleton.h"
#include <cstdio>
Singleton* Singleton::instance=new Singleton();
Singleton::Garbo Singleton::_garbo;
Singleton::Singleton()
{
printf("Constructor...\n");
int_a=0x55;
}
Singleton::Singleton(const Singleton&)
{
}
Singleton& Singleton::operator=(const Singleton&)
{
}
Singleton::~Singleton()
{
printf("%s...\n",__func__);
}
Singleton* Singleton::getInstance()
{
return instance;
}
int Singleton::getValue()
{
return int_a;
}
void Singleton::setValue(int new_value)
{
int_a=new_value;
}
main.cpp
#include <cstdio>
#include <pthread.h>
#include "singleton.h"
void* thread_func(void* arg);
int main()
{
printf("main begin...\n");
pthread_t a_thread;
Singleton* sgltn=Singleton::getInstance();
int val=sgltn->getValue();
printf("val=0x%X\n",val);
sgltn->setValue(0x33);
val=sgltn->getValue();
printf("val=0x%X\n",val);
pthread_create(&a_thread,nullptr,thread_func,nullptr);
printf("enter while...\n");
while(true)
{
sgltn=Singleton::getInstance();
val=sgltn->getValue();
printf("%s,val=0x%X\n",__func__,val);
}
return 0;
}
void* thread_func(void* arg)
{
printf("thread_func start...\n");
Singleton* sgltn=Singleton::getInstance();
int val=sgltn->getValue();
while(true)
{
sgltn=Singleton::getInstance();
val=sgltn->getValue();
printf("%s,val=0x%X\n",__func__,val);
}
}
多线程的工厂模式:
懒汉模式,双重锁定
singleton.h
#ifndef _SINGLETON_H_
#define _SINGLETON_H_
#include <pthread.h>
#include <cstdio>
class Singleton
{
public:
static Singleton* getInstance();
int getValue();
void setValue(int new_value);
virtual ~Singleton();
private:
Singleton();
Singleton(const Singleton&);
Singleton& operator=(const Singleton&);
int int_a;
static Singleton* instance;
static pthread_mutex_t sgltn_mutex;
/*This class is only used for garbage collection*/
class Garbo
{
public:
~Garbo()
{
if(Singleton::instance!=nullptr)
{
printf("%s\n",__func__);
delete Singleton::instance;
Singleton::instance=nullptr;
}
}
};
static Garbo _garbo;
};
#endif
singleton.cpp
#include "singleton2.h"
#include <cstdio>
Singleton* Singleton::instance=nullptr;
pthread_mutex_t Singleton::sgltn_mutex;
Singleton::Garbo Singleton::_garbo;
Singleton::Singleton()
{
pthread_mutex_init(&(Singleton::sgltn_mutex),nullptr);
printf("Constructor...\n");
int_a=0x55;
}
Singleton::Singleton(const Singleton&)
{
}
Singleton& Singleton::operator=(const Singleton&)
{
}
Singleton::~Singleton()
{
pthread_mutex_destroy(&(Singleton::sgltn_mutex));
printf("%s...\n",__func__);
}
Singleton* Singleton::getInstance()
{
if(Singleton::instance==nullptr)
{
pthread_mutex_lock(&(Singleton::sgltn_mutex));
if(Singleton::instance==nullptr)
{
Singleton::instance=new Singleton();
pthread_mutex_unlock(&(Singleton::sgltn_mutex));
return Singleton::instance;
}
else
{
pthread_mutex_unlock(&(Singleton::sgltn_mutex));
return Singleton::instance;
}
}
else
{
return Singleton::instance;
}
}
int Singleton::getValue()
{
return int_a;
}
void Singleton::setValue(int new_value)
{
int_a=new_value;
}
main.cpp
#include <cstdio>
#include <pthread.h>
#include "singleton2.h"
void* thread_func(void* arg);
int main()
{
printf("main begin...\n");
pthread_t a_thread;
Singleton* sgltn=nullptr;
int val=0;
pthread_create(&a_thread,nullptr,thread_func,nullptr);
printf("enter while...\n");
while(true)
{
sgltn=Singleton::getInstance();
val=sgltn->getValue();
printf("%s,val=0x%X\n",__func__,val);
}
return 0;
}
void* thread_func(void* arg)
{
printf("thread_func start...\n");
Singleton* sgltn=nullptr;
int val=0;
while(true)
{
sgltn=Singleton::getInstance();
val=sgltn->getValue();
printf("%s,val=0x%X\n",__func__,val);
}
}