设计模式初探----单例模式

news/2024/11/24 8:47:44/

概述

单例模式:保证类的实例化对象仅有一个,并提供一个访问他的全局访问点

应用场景

  • 表示文件系统的类,一个操作系统一定是只有一个文件系统,因此文件系统的类的实例有且仅有一个。
  • 打印机打印程序的实例,一台计算机可以连接好几台打印机,但是计算机上的打印程序只有一个,就可以通过单例模式来避免两个打印作业同时输出到打印机。

实现方式

单例模式可以通过全局或者静态变量的形式实现,这样比较简单,但是这样会影响封装性,难以保证别的代码不会对全局变量造成影响。

  • 默认的构造函数、拷贝构造函数、赋值构造函数声明为私有的,这样禁止在类的外部创建该对象;
  • 全局访问点也要定义成 静态类型的成员函数,没有参数,返回该类的指针类型。因为使用实例化对象的时候是通过类直接调用该函数,并不是先创建一个该类的对象,通过对象调用。

不安全的实现方式:
原因:考虑当两个线程同时调用 getInstance 方法,并且同时检测到 instance 是 NULL,两个线程会同时实例化对象,不符合单例模式的要求。

class Singleton{
private:static Singleton * instance;Singleton(){}Singleton(const Singleton& tmp){}Singleton& operator=(const Singleton& tmp){}
public:static Singleton* getInstance(){if(instance == NULL){instance = new Singleton();}return instance;}
};
Singleton* Singleton::instance = NULL;

懒汉模式

懒汉模式:直到第一次用到类的实例时才去实例化,上面是懒汉实现。

加锁

每次判断实例对象是否为空,都要被锁定,如果是多线程的话,就会造成大量线程阻塞。

#include <iostream>
#include <mutex>
#include <thread>
using namespace std;class Singleton {
private:static pthread_mutex_t mutex;static Singleton *instence; // c++11之后static本身就是线程安全的,不需要加锁Singleton() {pthread_mutex_init(&mutex, NULL);cout << "init" << endl;}Singleton(const Singleton &tmp) {}Singleton &operator=(const Singleton &tmp) {}public:static Singleton *getInstence() {pthread_mutex_lock(&mutex);	// 防止多个线程同时创建实例if (instence == NULL) {instence = new Singleton();}pthread_mutex_unlock(&mutex);return instence;}void fun() { cout << "fun" << endl; }
};
Singleton *Singleton::instence = NULL;
pthread_mutex_t Singleton::mutex;void test() { Singleton::getInstence()->fun(); }int main() {Singleton::getInstence()->fun();thread t(test);t.join();
}

输出:

init
fun
fun

内部静态变量

在全局访问点 getInstance 中定义静态实例。

class Singleton{
private:static pthread_mutex_t mutex;Singleton(){pthread_mutex_init(&mutex, NULL);}Singleton(const Singleton& temp){}Singleton& operator=(const Singleton& temp){}
public:static Singleton* getInstence(){ static Singleton instence;return &instence;}
};
pthread_mutex_t Singleton::mutex; 

饿汉模式

类定义的时候就实例化,本身就是线程安全的,不需要加锁

因为饿汉模式在定义类的时候,就会实例化,所以实例会一直占用着内存,而懒汉模式是在使用的时候才会实例化,因此懒汉模式的内存使用效率上会更高。

class Singleton{
private:static Singleton* instence;Singleton(const Singleton& temp){}Singleton& operator=(const Singleton& temp){}
protected:Singleton(){} 
public:static Singleton* getInstence(){ return instence;    }
};
Singleton* Singleton::instence = new Singleton();

http://www.ppmy.cn/news/76851.html

相关文章

【微博-自定义Cell-创建子控件 Objective-C语言】

一、自定义Cell 1.既然我们要自定义Cell,这个自定义Cell,属于MVC哪个部分, 这个Cell类,属于MVC哪个部分, Model、Controller、还是View, View吧, 所以说,应该在这里去新建一个类, 在这里去新建一个类,右键,New File,

Hiredis的基本使用

目录 前言 一.hiredis的安装 二.同步API 2.1.连接Redis数据库 2.1.1 无超时时间&#xff0c;阻塞等待连接 2.1.2 设置超时时间&#xff0c;阻塞等待连接。 2.1.3 非阻塞&#xff0c;不管连接与否&#xff0c;立即返回。 2.2.执行命令 2.2.1 返回执行上下文 2.2.2 没有返回执…

Linux内存简介

Linux内存简介 概述 为何MemTotal小于RAM容量 [rootiZbp1dphe2bpv39op1g123Z ~]# dmesg | grep Memory [ 1.391064] Memory: 131604168K/134217136K available (14346K kernel code, 9546K rwdata, 9084K rodata, 2660K init, 7556K bss, 2612708K reserved, 0K cma-reserved) …

第三十五回:AboutDialog Widget

文章目录 概念介绍使用方法示例代码 我们在上一章回中介绍了 AlertDialog Widget相关的内容,本章回中将介绍 AboutDialog Widget.闲话休提&#xff0c;让我们一起Talk Flutter吧。 概念介绍 我们在这里说的AboutDialog是一种弹出式窗口&#xff0c;和上一章回中介绍的AlertD…

“向上管理”的7个最佳实践:如何管理你的老板?

向上管理是一种管理技巧&#xff0c;它指的是如何有效地管理你的老板。这种技巧可以帮助你更好地与老板沟通&#xff0c;提高工作效率&#xff0c;增加工作成就感。本文将介绍七个最佳实践&#xff0c;帮助你学会如何向上管理。 1. 了解老板的需求和期望 了解老板的需求和期望…

MySQL视图的使用与多表视图查询

MySQL视图是一种虚拟的表&#xff0c;它是基于查询结果的表的可视化表示。视图提供了一种简化和抽象化数据库查询的方式&#xff0c;可以隐藏复杂的查询逻辑&#xff0c;简化数据访问&#xff0c;并提供了一致性和安全性的控制。在MySQL中&#xff0c;视图的使用广泛应用于各种…

中文Python(5)中文Python的while条件循语句

中文Python&#xff08;5&#xff09;中文Python的while条件循语句 Python是一种流行的编程语言&#xff0c;其简单而直观的语法吸引了很多人学习和使用。中文Python则是针对中文用户开发的一种版本。中文Python原先为了给不懂编写程序的人写量化程序&#xff0c;我们开发了中…

SpringMVC执行原理

目录结构 pom.xml依赖 <dependencies><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>3.8.1</version><scope>test</scope></dependency><!-- https://mvnrepository.co…