1. 巴基的订单
在海贼世界中,巴基速递是巴基依靠手下强大的越狱犯兵力,组建的集团海贼派遣公司,它的主要业务是向世界有需要的地方输送雇佣兵(其实是不干好事儿)。
自从从特拉法尔加罗
和路飞
同盟击败了堂吉诃德家族
,战争的市场对雇佣兵的依赖越来越大。订单便源源不断的来了。此时我们来分析一个问题:巴基是怎么接单并且派单的呢?
简单来说,巴基肯定是有一个账本用于记录下单者信息,下单者的需求以及下单的时间,然后根据下单的先后顺序选择合适的人手进行派单。从程序猿的视角可以这样认为,这个账本其实就相当于一个任务队列:
- 有一定的容量,可以存储任务
- 按照下单的先后顺序存储并处理任务 – 典型的队列特性:
先进先出
对于巴基来说把所有的订单全部记录到一个账本上就够了,如果将其平移到项目中,也就意味着应用程序在运行过程中存储任务的任务队列一个足矣,弄太多反而冗余,不太好处理了。
在一个项目中,全局范围内,某个类的实例有且仅有一个,通过这个唯一实例向其他模块提供数据的全局访问,这种模式就叫单例模式。单例模式的典型应用就是任务队列。
2. 独生子女
如果使用单例模式,首先要保证这个类的实例有且仅有一个,也就是说这个对象是独生子女,如果我们实施计划生育只生一个孩子,不需要也不能给再他增加兄弟姐妹。因此,就必须采取一系列的防护措施。对于类来说以上描述同样适用。涉及一个类多对象操作的函数有以下几个:
构造函数:
创建一个新的对象拷贝构造函数:
根据已有对象拷贝出一个新的对象拷贝赋值操作符重载函数:
两个对象之间的赋值
为了把一个类可以实例化多个对象的路堵死,可以做如下处理:
- 构造函数私有化,在类内部只调用一次,这个是可控的。
- 由于使用者在类外部不能使用构造函数,所以在类内部创建的这个唯一的对象必须是静态的,这样就可以通过类名来访问了,为了不破坏类的封装,我们都会把这个静态对象的访问权限设置为私有的。
- 在类中只有它的静态成员函数才能访问其静态成员变量,所以可以给这个单例类提供一个静态函数用于得到这个静态的单例对象。
-
拷贝构造函数私有化或者禁用(
使用 = delete
) -
拷贝赋值操作符重载函数私有化或者禁用(
从单例的语义上讲这个函数已经毫无意义,所以在类中不再提供这样一个函数,故将它也一并处理一下。
)
由于单例模式就是给类创建一个唯一的实例对象,所以它的UML类图是很简单的:
因此,定义一个单例模式的类的示例代码如下:
// 定义一个单例模式的类
class Singleton
{
public:
// = delete 代表函数禁用, 也可以将其访问权限设置为私有
Singleton(const Singleton& obj) = delete;
Singleton& operator=(const Singleton& obj) = delete;
static Singleton* getInstance();
private:
Singleton() = default;
static Singleton* m_obj;
};
在实现一个单例模式的类的时候,有两种处理模式:
饿汉模式
懒汉模式
3. 饿汉模式
饿汉模式就是在类加载的时候立刻进行实例化
,这样就得到了一个唯一的可用对象。关于这个饿汉模式的类的定义如下:
//