介绍
几个重点:
- 构造函数为private
- 提供一个获取单例对象指针的函数
- 一个静态指针成员存储单例对象
注意:
- 获取单例对象也可以获取对象引用,但要注意拷贝构造函数和赋值运算符
- 如果有多线程访问单例,需要注意线程同步
UML类图:
简单示例:
懒汉和饿汉模式:
#ifndef SIMPLE_SINGLETON_H
#define SIMPLE_SINGLETON_H
#include <iostream>
using namespace std;
/**
* @brief The LazySingleton class
* 懒汉模式
*/
class LazySingleton
{
public:
static LazySingleton *getInstance()
{
if( m_instance == nullptr)
m_instance = new LazySingleton;
return m_instance;
}
static void freeInstance()
{
if( m_instance != nullptr )
delete m_instance;
m_instance = nullptr;
}
private:
LazySingleton()
{
cout<<" LazySingleton 构造函数执行"<<endl;
}
static LazySingleton *m_instance ;
};
LazySingleton *LazySingleton::m_instance = nullptr;
/**
* @brief The HungrySingleton class
* 饿汉模式,一般用不到
*/
class HungrySingleton
{
public:
static HungrySingleton *getInstance()
{
if( m_instance == nullptr)
m_instance = new HungrySingleton;
return m_instance;
}
static void freeInstance()
{
if( m_instance != nullptr )
delete m_instance;
m_instance = nullptr;
}
private:
HungrySingleton()
{
cout<<" HungrySingleton 构造函数执行"<<endl;
}
static HungrySingleton *m_instance ;
};
HungrySingleton *HungrySingleton::m_instance = new HungrySingleton;
#endif // SIMPLE_SINGLETON_H
懒汉线程安全模式:
#ifndef THREAD_SINGLETON_H
#define THREAD_SINGLETON_H
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
using namespace std;
void printids(const char *s)
{
pid_t pid;
pthread_t tid;
pid = getpid();
tid = pthread_self();
printf("%s pid %u tid %u (0x%x)\n", s, (unsigned int) pid,
(unsigned int) tid, (unsigned int) tid);
}
class LazySingleton
{
public:
static LazySingleton *getInstance()
{
// if( m_instance == nullptr)
// {
// m_count++;
// m_instance = new LazySingleton;
// }
if( m_instance == nullptr)
{
pthread_mutex_lock(&m_mutex_lock);
if( m_instance == nullptr)
{
m_count++;
m_instance = new LazySingleton;
}
pthread_mutex_unlock(&m_mutex_lock);
}
return m_instance;
}
static void freeInstance()
{
if( m_instance != nullptr )
delete m_instance;
pthread_mutex_destroy(&m_mutex_lock);
m_instance = nullptr;
}
void showMessage()
{
cout<<"LazySingleton message!"<<endl;
}
private:
LazySingleton()
{
cout<<" LazySingleton 构造函数执行开始"<<endl;
sleep(2);
cout<<" LazySingleton 构造函数执行 ["<<m_count<<"] 次"<<endl;
}
static LazySingleton *m_instance ;
static int m_count;
static pthread_mutex_t m_mutex_lock;
};
LazySingleton *LazySingleton::m_instance = nullptr;
int LazySingleton::m_count = 0;
pthread_mutex_t LazySingleton::m_mutex_lock = PTHREAD_MUTEX_INITIALIZER;
void *thr_fn(void *arg)
{
// printids("new thread: ");
LazySingleton::getInstance()->showMessage();
return nullptr;
}
#endif // THREAD_SINGLETON_H
线程安全,调用方式:
printids("main thread:");
int err;
pthread_t ntid[3];
for (int i=0 ; i<3 ; i++) {
err = pthread_create(&ntid[i], NULL, thr_fn, NULL);
if (err != 0)
printf("can't create thread: %s\n", strerror(err));
}
for (int i=0; i < 3 ; i++) {
pthread_join(ntid[i],NULL);
}
内部静态类(懒汉)方式:
class StackSingleton
{
public:
static StackSingleton *getInstance()
{
//内部静态实例的懒汉模式
pthread_mutex_lock(&m_mutex_lock);
static StackSingleton _instance ;
pthread_mutex_unlock(&m_mutex_lock);
return &_instance;
}
void printS()
{
cout<<"栈方式的单例模式..."<<endl;
}
private:
StackSingleton()
{
cout<<" StackSingleton 构造函数执行"<<endl;
}
static pthread_mutex_t m_mutex_lock;
};
pthread_mutex_t StackSingleton::m_mutex_lock = PTHREAD_MUTEX_INITIALIZER;