C++八股--three day --设计模式之单例和工厂

对于C++编程中的思想,最常见的就是考察设计模式了

那么我们在面试中常考的设计模式包含以下几种:单例模式,

接下来我们按顺序介绍

1.单例模式:

一个类只能创建一个实例:常应用于日志模块,数据库模块

单例模式需要具备以下4要素

1.构造函数私有化

2.禁用拷贝构造,赋值重载

类名 (const 类名 &) = delete; 禁用拷贝构造

类名 &operator= (const 类名&)= delete; 禁用赋值构造

上述两个方法确保构造函数只会被调用一次

3.定义唯一对象,static:类内定义,类外初始化

4.定义接口获取实例:【使用静态方法】原因:普通方法依赖对象,现在不存在对象

那么所需条件已经具备,那么我们可以着手写一个单例模式的示例

class Singleton{

public:

static Singleton * getInstance()//获取唯一实例对象的接口方法

{

return &instance;//注意这里返回的为地址,需要用指针接收

}

private:

Singleton(){}

Singleton(const Singleton&) = delete;

Singleton &operator= (const Singleton&) = delete;

static Singleton instance;//注意这里我定义的实例

};

Singleton Singleton::instance; //类外初始化

想必你肯定觉得上述代码很简单,只需要考虑四要素即可

在实际考察中我们还会将其结合懒汉和饿汉的设计,下面给出具体的介绍

饿汉模式下的单例模式:一定是线程安全的:在软件启动时初始化,肯定会延长软件启动时间

还没有获取实例对象,实例对象就已经产生了。

其实我们的上述代码就是饿汉式的

懒汉模式下的单例模式:需要注意的是我们需要的是多线程安全。

只有获取的时候才产生实例,注意与懒汉模式的区别

//需要加锁实现互斥

std::mutex mtx; //定义锁

class Singleton{

public:

static Singleton * getInstance()//获取唯一实例对象的接口方法

{

if(instance == nullptr)

{

lock_guard<std::mutex> guard(mtx);//加锁

if(instance == nullptr)

{

instance = new Singleton();

}

}

return instance;

}

private:

static Singleton *volatile instance;//注意这里需要使用volatile修饰,避免对该变量优化

Singleton(){}

Singleton(const Singleton&) = delete;

Singleton &operator= (const Singleton&) = delete;

};

Singleton* Singleton::instance = nullptr; //类外初始化

上述做法使用锁+双重判断实现线程安全的懒汉模式,下面提供另一种模式

核心为static关键字:第一次运行的时候才初始化,note:C++11保证static定义是线程安全的

class Singleton{

public:

static Singleton * getInstance()//获取唯一实例对象的接口方法

{

static Singleton instance;

return &instance;

}

private:

Singleton(){}

Singleton(const Singleton&) = delete;

Singleton &operator= (const Singleton&) = delete;

};

Singleton* Singleton::instance = nullptr; //类外初始化

好,上述已经成功介绍了单例模式

那么接下来为第二个设计模式

2.工厂模式

工厂模式分为三种:简单工厂(这个实际上不包含),工厂方法,抽象工厂

为什么叫工厂:主要是封装了对象的创建

下面以汽车为例

class Car

{

public:

Car(string name) : Name(name) { }

virtual void show() = 0;

protected:

string Name;

};

class BaoMa :public Car

{

public:

BaoMa(string name) : Car(name) { }

void show(){ cout<<"get a BaoMa"<<endl; }

};

class AoDi :public Car

{

public:

AoDi(string name) : Car(name) { }

void show(){ cout<<"get a Aodi"<<endl; }

};

enum CarType{ baoma,aodi }; //定义枚举类型

class SimpleFactory

{

public:

Car* createCar(CarType ct)

{

switch(ct)

{

case baoma:

return new BaoMa("X1");

case aodi:

return new AoDi("A6");

default:

break;

}

return nullptr;

}

};

上述代码封装了对象的创建,函数调用的时候只需要通过工厂调用对应的函数即可,而不需要了解内部实现

unique_ptr<SimpleFactory> factorty(new SimpleFactory());

创建一个宝马

unique_ptr<Car> p1(factory->createCar(BaoMa));

p1->show();

简单工厂不好的地方:

1.不同汽车的创建应该在不同工厂

2.工厂应该对修改关闭

基于这样的缺点:工厂方法进行了改进

//创建工厂基类:后面各种工厂直接继承就可以了

class Factory

{

public:

virtual Car * createCar(string name) = 0;

};

//宝马工厂

class BaoMaFactory:public Factory

{

public:

Car * createCar(string name)

{

return new BaoMa(name);

}

};

在实际上,通常有关联关系的产品系列在同一工厂,工厂方法无法实现此功能

假设我还要在工厂中生产车灯,那么就需要使用抽象工厂这一个概念

抽象工厂:对一组有关联关系的产品簇提供产品对象的统一创建

// 车灯基类

class Light

{

pubilc:

virtual void show()=0;

};

classs BaoMaLight : public Light

{

public:

void show(){ cout<<"get a Light"<<endl; }

};

//抽象工厂

class AbstractFactory

{

public:

virtual Car * createCar(string name) = 0;

virtual Light * createCarLight() = 0;

};

这些代码都比较简单,只要理解思想很容易就可以写出来,后面的代码就不再赘述了

工厂方法:提供了一个纯虚函数创建产品,定义派生类负责创建对应的产品,可以做到不同产品在不同工厂创建,实现对现有工厂和产品修改封闭

抽象工厂:把有关联关系的,属于一个产品簇的所有产品创建的接口函数,放到一个抽象工厂中

相关推荐
浅念-4 小时前
C++入门(2)
开发语言·c++·经验分享·笔记·学习
苏渡苇4 小时前
优雅应对异常,从“try-catch堆砌”到“设计驱动”
java·后端·设计模式·学习方法·责任链模式
小羊不会打字4 小时前
CANN 生态中的跨框架兼容桥梁:`onnx-adapter` 项目实现无缝模型迁移
c++·深度学习
Max_uuc5 小时前
【C++ 硬核】打破嵌入式 STL 禁忌:利用 std::pmr 在“栈”上运行 std::vector
开发语言·jvm·c++
近津薪荼5 小时前
dfs专题4——二叉树的深搜(验证二叉搜索树)
c++·学习·算法·深度优先
短剑重铸之日5 小时前
《设计模式》第十一篇:总结
java·后端·设计模式·总结
艾莉丝努力练剑5 小时前
【Linux:文件】Ext系列文件系统(初阶)
大数据·linux·运维·服务器·c++·人工智能·算法
Once_day6 小时前
C++之《程序员自我修养》读书总结(1)
c语言·开发语言·c++·程序员自我修养
Trouvaille ~6 小时前
【Linux】TCP Socket编程实战(一):API详解与单连接Echo Server
linux·运维·服务器·网络·c++·tcp/ip·socket
feasibility.6 小时前
AI 编程助手进阶指南:从 Claude Code 到 OpenCode 的工程化经验总结
人工智能·经验分享·设计模式·自动化·agi·skills·opencode