八大常见的设计模式
设计模式是一种编写代码的方式,旨在解决常见的软件设计问题。这些模式提供了代码重用和易于维护的解决方案。本文将讲解几种常见的设计模式,并使用 C++ 编写相应的代码示例
1、单例模式
单例模式确保一个类只有一个实例,并提供一个全局访问点
饿汉式单例模式
在程序启动时就会创建一个唯一的单例对象
饿汉单例模式在类加载时就初始化实例,线程安全
#include<iostream>
using namespace std;
class Singleton{
private:
//构造函数私有化
Singleton();
//拷贝构造私有化
Singleton(const Singleton& p){};
//赋值运算符重载私有化
Singleton operator=(const Singleton& p){};
//静态实例
static Singleton* instance;
public:
//获取单例实例
static Singleton* getInstance(){
return instance;
}
void print(){
std::cout<<"Hello Singleton..."<<std::endl;
}
};
//在类加载时初始化实例
Singleton* Singleton::instance = new Singleton();
int main(){
Singleton* singleton = Singleton::getInstance();
singleton->print();
return 0;
}
饿汉模式的优点在于如果在多线程并发的环境下频繁使用可以降低资源的竞争,提高响应速度
但是如果在程序开始时要加载插件,比较大的配置文件,初始化网络链接,读取文件的一方面比较费时,而且还可能用不到,此时就提出了懒汉(延迟加载)模式
懒汉式单例模式
在使用时才创建实例对象,不会在一开始就创建实例化对象而是等到要使用时才进行创建
懒汉式单例模式在第一次使用时初始化实例,懒加载,节省资源,但需要考虑线程安全
#include<iostream>
#include<mutex>
using namespace std;
class Singleton{
private:
static Singleton* instance;
static std::mutex mutex;
Singleton(){}
public:
static Singleton* getInstance(){
if(instance == nullptr){
std::lock_guard<std::mutex> lock(mutex);
if(instance == nullptr){
instance = new Singleton();
}
}
return instance;
}
void print(){
std::cout<<"Hello Singleton.."<<std::endl;
}
};
//静态成员变量初始化
Singleton* Singleton::instance = nullptr;
std::mutex Single::mutex;
int main(){
Singleton* singleton = Singleton::getInstance();
singleton->print();
return 0;
}
懒汉的基础结构与饿汉相同,都要做到防拷贝和构造函数私有化。仅在程序开始时创建一个对象的空指针,在需要时创建对象,使其不为空即可
但考虑线程安全的问题引入了锁
饿汉不存在线程安全问题,因为只有一个对象,每个线程都只能看到唯一的一个实例对象
注意:
1、如果在需要创建实例对象时,两个线程并行走到此处,都发现该指针为空,就会创建两个实例化对象,此时引入了锁,每次只能进入一个,当第二个线程再次进入时发现该指针已不为空,就无法再创建对象,解决了线程安全问题
2、如果存在大量线程,每次都要进行加锁解锁的操作,大大降低了程序的效率,所以进行双检查,避免无意义的锁操作