单例模式:保证某个类在项目中只能实例化一次,减小资源的浪费
懒汉式:在调用静态方法的时候分配内存
饿汉式:直接分配内存
懒汉式
#include <iostream>
using namespace std;
/*
单例模式:保证某个类在项目中只能实例化一次,减小资源的浪费
*/
class socketer
{
private:
socketer()
{
cout << "socketer执行" << endl;
}
~socketer()
{
delete _socket;
_socket = NULL;
cout << "_socket被释放" << endl;
}
public:
static socketer *getSocketer()
{
if (_socket == NULL)
{
_socket = new socketer;
}
return _socket;
}
void deleteSocket()
{
if (_socket != NULL)
{
delete _socket;
_socket = NULL;
cout << "_socket被释放" << endl;
}
}
static socketer *_socket;
};
socketer *socketer::_socket = NULL;
int main()
{
socketer *p1 = socketer::getSocketer();
socketer *p2 = socketer::getSocketer();
cout << p1 << endl;
cout << p2 << endl;
//p1->deleteSocket();
//p1 == p2 即p1,p2指向同一块内存空间
return 0;
}
当懒汉式遇到多线程的时候,会引起资源竞争问题,也就是,类会实例化多次,
即懒汉式遇到多线程时,不是线程安全函数,需要使用mutex进行线程保护。
以下测试代码中可以将tex.lock();tex.unlock();注释掉,会发现构造函数执行两次,即类被实例化两次
#include <iostream>
#include <thread>
#include <mutex>
using namespace std;
mutex tex;
class socketer
{
private:
socketer()
{
cout << "socketer执行" << endl;
}
~socketer()
{
delete _socket;
_socket = NULL;
cout << "_socket被释放" << endl;
}
public:
static socketer *getSocketer()
{
tex.lock();
if (_socket == NULL)
{
_socket = new socketer;
}
tex.unlock();
return _socket;
}
void threadText()
{
getSocketer();
}
void deleteSocket()
{
if (_socket != NULL)
{
delete _socket;
_socket = NULL;
cout << "_socket被释放" << endl;
}
}
static socketer *_socket;
};
socketer *socketer::_socket = NULL;
int main()
{
socketer *p1 ;
socketer *p2 ;
thread thread1(&socketer::threadText, p1);
thread thread2(&socketer::threadText, p2);
thread1.join();
thread2.join();
return 0;
}
饿汉式
类实例化在main函数之前
#include <iostream>
using namespace std;
/*
单例模式:保证某个类在项目中只能实例化一次,减小资源的浪费
*/
class socketer
{
private:
socketer()
{
cout << "socketer执行" << endl;
}
~socketer()
{
delete _socket;
_socket = NULL;
cout << "_socket被释放" << endl;
}
public:
static socketer *getSocketer()
{
return _socket;
}
void deleteSocket()
{
if (_socket != NULL)
{
delete _socket;
_socket = NULL;
cout << "_socket被释放" << endl;
}
}
static socketer *_socket;
};
socketer *socketer::_socket = new socketer;
int main()
{
socketer *p1 = socketer::getSocketer();
socketer *p2 = socketer::getSocketer();
cout << p1 << endl;
cout << p2 << endl;
//p1->deleteSocket();
//p1 == p2 即p1,p2指向同一块内存空间
return 0;
}
单例模式个人小建议
现在电脑资源十分丰富,单例模式尽量使用饿汉式
如果你的代码需要运行在资源十分紧张的嵌入式系统下,可以选择使用懒汉式,但是需要进行线程保护