单例模式的两种实现以及特殊类的设计
实现单例模式
单例模式是一种设计模式,在实战中经常会用到。其意思是创建一个类这个类只能唯一的创建一个对象,如果之后还想用这个类创建新对象的时候都会返回最开始创建的呢个对象。
要实现这一点有两种思路,分别成为懒汉模式和饿汉模式。
饿汉模式
饿汉模式是在程序启动时就夹在所有需要资源的设计模式,不涉及线程安全的问题,用这种思想实现单例模式时需要在程序一开始就直接声明对象,需要使用对象就返回对象即可。但是坏处是程序启动时会消耗时间可能会造成程序启动缓慢。以空间换时间的思想。
成员变量静态化——资源共享;构造函数私有化。
#include <iostream>
class Singleton1
{
public:
//外留接口
static Singleton1* GetInstence()
{
return &_singleton;
}
private:
//防拷贝,禁用构造,拷贝构造和赋值
Singleton1()
{
}
Singleton1(const Singleton1&);
Singleton1& operator=(const Singleton1&);
static Singleton1 _singleton;
};
Singleton1 Singleton1::_singleton;
懒汉模式
懒汉模式就是在第一次使用时才会创建对象,因此我们需要对变量进行判断考虑到线程安全我们需要对其加锁。懒汉模式的坏处是可能造成程序运行卡顿。
资源使用静态指针——资源共享,延时加载。
二次判断,减少锁冲突,提高效率。
class Singleton2
{
public:
static Singleton2* GetInstence()
{
//双重判断避免不必要的锁竞争
if(_pSingleton == nullptr)
{
//为了线程安全需要加锁
_mtx.lock();
if (_pSingleton == nullptr)
{
_pSingleton = new Singleton2;
}
_mtx.unlock();
}
return _pSingleton;
}
private:
Singleton2(){}
Singleton2(const Singleton2&);
Singleton2& operator=(const Singleton2&);
static std::mutex _mtx;
static Singleton2* _pSingleton;
};
std::mutex Singleton2::_mtx;
Singleton2* Singleton2::_pSingleton = nullptr;
写一个只能在堆上创建对象的类
思路
1、将构造函数,赋值构造函数全部封装为私有,不允许外部直接调用构造。
2、单独写一个静态函数提供在堆上创建对象的接口。
实现
#include <iostream>
using namespace std;
class HeapOnly
{
public:
//开放构造接口
static HeapOnly* Create()
{
cout << "create int heap" << endl;
return new HeapOnly();
}
~HeapOnly()
{
cout << "destorying" << endl;
}
private:
//构造函数私有化
HeapOnly(){}
HeapOnly(const HeapOnly&){}
};
int main()
{
HeapOnly* heapOnly = HeapOnly::Create();
delete heapOnly;
}
[root@localhost 内存管理]$ ./HeapOnlyClass
create int heap
destorying
写一个只能在栈上创建对象的类
思路一
1、将构造函数,赋值构造函数全部封装为私有,不允许外部直接调用构造。
2、单独写一个静态函数提供在栈上创建对象的接口。
#include <iostream>
using namespace std;
class StackOnly
{
public:
static StackOnly Create()
{
//创建匿名对象
return StackOnly();
}
static StackOnly a;
~StackOnly()
{
cout << "destorying" << endl;
}
private:
StackOnly()
{
cout << "create in stack" << endl;
}
StackOnly(const StackOnly&){}
};
int main()
{
StackOnly::a = StackOnly::Create();
}
[root@localhost 内存管理]$ ./StackOnlyClass
create in stack
destorying
思路二
1、直接将operator new和operator delete重载并定义为私有。
#include <iostream>
using namespace std;
class StackOnly
{
public:
StackOnly()
{
cout << "create in stack" << endl;
}
~StackOnly()
{
cout << "destorying" << endl;
}
private:
void* operator new(size_t size){}
void operator delete(void* p){}
};
int main()
{
StackOnly p;
}