设计模式( Design Pattern )是一套被反复使用、多数人知晓的、经过分类的、代码设计经验的,目的是为了代码可重用性、让代码更容易被他人理解、保证代码可靠性。
**单例模式:**一个类只能创建一个对象,即单例模式,该模式可以保证系统中该类只有一个实例,并提供一个 访问它的全局访问点,该实例被所有程序模块共享。
两种实现模式:
1. 饿汉模式:程序执行前就创建了,全局只有一个实例对象。
cpp
class A
{
public:
static A* create()
{
return &_a;
}
private:
int _port;
// 静态资源全局只有一份
// 属于整个类,受类域影响
static A _a;
private:
A() {}
A(const A& copy) = delete;
A& operator=(const A& copy) = delete;
};
A A::_a;
借助全局对象在程序运行之前创建初始化,每次访问都是同一个对象。
缺点:
如果程序里出现大量的懒汉模式的单例,程序运行起来要预先创建大量的资源,导致程序启动慢。
如果类与类之间有相互依赖关系,全局对象创建顺序可能是乱的,那么就会导致A需要用B类,A类先创建,而B类未创建。
2. 懒汉模式:和饿汉模式相反,是在程序运行时有且只有一个实例对象
cpp
class A
{
public:
static A* create()
{
// C++11之前存在线程安全问题
// 可能多个线程同时调用 new 在调用,operator new
// 会导致 new 了多个 A 给 a*,所以要加锁
static A *a = new A;
return a;
}
private:
int _port;
private:
A() {}
A(const A& copy) = delete;
A& operator=(const A& copy) = delete;
};
另一种方式:
cpp
class A
{
public:
static A* create()
{
// 如果有大量的获取单例对象
// 就不用进行频繁的加锁解锁
if (_a == nullptr)
{
// C++11之前 对多线程情况下的保护
_mt.lock();
if (_a == nullptr)
{
_a = new A;
}
_mt.unlock();
}
return _a;
}
// 析构静态资源,程序结束自动调用
class Release
{
public:
~Release() { if (A::_a != nullptr)delete A::_a; }
};
static Release _RL;
private:
// 程序执行之前创建,大小忽略不计
static A* _a;
static mutex _mt;
private:
A() {}
A(const A& copy) = delete;
A& operator=(const A& copy) = delete;
};
// 初始化静态成员
A* A::_a = nullptr;
mutex A::_mt;
A::Release A::_RL;
缺点:在C++11之前,多线程环境下有线程安全问题,要加锁保护。