【C++】设计模式:建造者、原型、单例

news2024/12/27 13:38:44

😏★,°:.☆( ̄▽ ̄)/$:.°★ 😏
这篇文章主要介绍设计模式:建造者、原型、单例。
学其所用,用其所学。——梁启超
欢迎来到我的博客,一起学习,共同进步。
喜欢的朋友可以关注一下,下次更新不迷路🥞

文章目录

    • :smirk:1. 建造者模式
    • :blush:2. 原型模式
    • :satisfied:3. 单例模式

😏1. 建造者模式

建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。

建造者模式的结构包含以下几个角色:

  • 抽象建造者(AbstractBuilder):创建一个Product对象的各个部件指定的抽象接口;
  • 具体建造者(ConcreteBuilder):实现AbstractBuilder的接口,实现各个部件的具体构造方法和装配方法,并返回创建结果。
  • 产品(Product):具体的产品对象
  • 指挥者(Director): 构建一个使用Builder接口的对象,安排复杂对象的构建过程,客户端一般只需要与Director交互,指定建造者类型,然后通过构造函数或者setter方法将具体建造者对象传入Director。它主要作用是:隔离客户与对象的生产过程,并负责控制产品对象的生产过程
#include <iostream>
#include <string>

// 产品类
class Product {
public:
    void setPartA(const std::string& partA) {
        partA_ = partA;
    }

    void setPartB(const std::string& partB) {
        partB_ = partB;
    }

    void setPartC(const std::string& partC) {
        partC_ = partC;
    }

    void show() {
        std::cout << "Product parts: " << partA_ << ", " << partB_ << ", " << partC_ << std::endl;
    }

private:
    std::string partA_;
    std::string partB_;
    std::string partC_;
};

// 抽象建造者类
class Builder {
public:
    virtual void buildPartA() = 0;
    virtual void buildPartB() = 0;
    virtual void buildPartC() = 0;
    virtual Product* getProduct() = 0;
};

// 具体建造者类 A
class ConcreteBuilderA : public Builder {
public:
    void buildPartA() override {
        product_->setPartA("PartA of Product A");
    }

    void buildPartB() override {
        product_->setPartB("PartB of Product A");
    }

    void buildPartC() override {
        product_->setPartC("PartC of Product A");
    }

    Product* getProduct() override {
        return product_;
    }

private:
    Product* product_ = new Product();
};

// 指挥者类
class Director {
public:
    void construct(Builder* builder) {
        builder->buildPartA();
        builder->buildPartB();
        builder->buildPartC();
    }
};

int main() {
    Director director;

    ConcreteBuilderA builderA;
    director.construct(&builderA);

    Product* productA = builderA.getProduct();
    productA->show();

    delete productA;

    return 0;
}

适用环境:

  • 需要生成的产品对象有复杂的内部结构(通常包含多个成员变量);
  • 产品对象内部属性有一定的生成顺序;
  • 同一个创建流程适用于多种不同的产品。

😊2. 原型模式

原型模式:使用原型实例指定待创建对象的类型,并且通过复制这个原型来创建新的对象。

原型式的结构包含以下几个角色:

  • 抽象原型类(AbstractPrototype):声明克隆clone自身的接口
  • 具体原型类(ConcretePrototype):实现clone接口
  • 客户端(Client):客户端中声明一个抽象原型类,根据客户需求clone具体原型类对象实例

原型模式可以说是“复制”,即克隆,但这个复制不是代码的复制,而是将对象包含的所有属性都创建一份拷贝。但不同的复制操作,可能会产生两种不同的拷贝,即浅拷贝和深拷贝。

#include <iostream>

// 原型基类
class Prototype {
public:
    virtual Prototype* clone() = 0;
    virtual void show() = 0;
};

// 具体原型类 A
class ConcretePrototypeA : public Prototype {
public:
    Prototype* clone() override {
        return new ConcretePrototypeA(*this);
    }

    void show() override {
        std::cout << "ConcretePrototypeA" << std::endl;
    }
};

// 具体原型类 B
class ConcretePrototypeB : public Prototype {
public:
    Prototype* clone() override {
        return new ConcretePrototypeB(*this);
    }

    void show() override {
        std::cout << "ConcretePrototypeB" << std::endl;
    }
};

int main() {
    ConcretePrototypeA prototypeA;
    Prototype* clonedA = prototypeA.clone();
    clonedA->show();
    delete clonedA;

    ConcretePrototypeB prototypeB;
    Prototype* clonedB = prototypeB.clone();
    clonedB->show();
    delete clonedB;

    return 0;
}

适用环境:

  • 当创建新的对象实例较为复杂时,原型模式可以简化创建过程;
  • 需要避免使用分层次的工厂类来创建分层次的对象,并且类的实例对象只有一个或很少几个的组合状态,通过复制原型对象得到新实例,比通过使用构造函数创建一个新实例会更加方便。

😆3. 单例模式

单例模式是指在整个系统生命周期内,保证一个类只能产生一个实例,确保该类的唯一性。

单例模式可以保证线程安全,即给共享的资源加把锁,保证每个资源变量每时每刻至多被一个线程占用。

单例模式可以分为懒汉式和饿汉式,两者之间的区别在于创建实例的时间不同。懒汉式只有使用时才会创建实例,这种情况要考虑线程安全;饿汉式初始化就会创建实例,需要时直接调用,不用考虑安全问题。

饿汉式实现:

头文件:

// 饿汉实现 /
class Singleton
{
public:
    // 获取单实例
    static Singleton* GetInstance();

    // 释放单实例,进程退出时调用
    static void deleteInstance();

    // 打印实例地址
    void Print();

private:
    // 将其构造和析构成为私有的, 禁止外部构造和析构
    Singleton();
    ~Singleton();

    // 将其拷贝构造和赋值构造成为私有函数, 禁止外部拷贝和赋值
    Singleton(const Singleton &signal);
    const Singleton &operator=(const Singleton &signal);

private:
    // 唯一单实例对象指针
    static Singleton *g_pSingleton;
};

源文件:

// 代码一运行就初始化创建实例 ,本身就线程安全
Singleton* Singleton::g_pSingleton = new (std::nothrow) Singleton();

Singleton* Singleton::GetInstance()
{
    return g_pSingleton;
}

void Singleton::deleteInstance()
{
    if (g_pSingleton)
    {
        delete g_pSingleton;
        g_pSingleton = nullptr;
    }
}

void Singleton::Print()
{
    std::cout << "我的实例内存地址是:" << this << std::endl;
}

Singleton::Singleton()
{
    std::cout << "构造函数" << std::endl;
}

Singleton::~Singleton()
{
    std::cout << "析构函数" << std::endl;
}

main程序:

#include <iostream>
#include <memory>
#include <mutex>

class Singleton {
public:
    static std::shared_ptr<Singleton> getSingleton();

    void print() {
        std::cout << "Hello World." << std::endl;
    }

    ~Singleton() {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }

private:
    Singleton() {
        std::cout << __PRETTY_FUNCTION__ << std::endl;
    }
};

static std::shared_ptr<Singleton> singleton = nullptr;
static std::once_flag singletonFlag;

std::shared_ptr<Singleton> Singleton::getSingleton() {
    std::call_once(singletonFlag, [&] {
        singleton = std::shared_ptr<Singleton>(new Singleton());
    });
    return singleton;
}

请添加图片描述

以上。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1499731.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

2024年泰迪智能科技合作伙伴战略大会暨产教融合实训基地落成仪式圆满结束

2024年泰迪智能科技合作伙伴战略大会 暨产教融合实训基地落成仪式 3月6日&#xff0c;2024年泰迪智能科技合作伙伴战略大会暨产教融合实训基地落成仪式在泰迪智能科技产教融合实训基地举行&#xff0c;本次合作伙伴战略大会围绕“龙腾山海&#xff0c;共赴新程 ”主题开展&…

小程序开发平台源码系统 功能强大 各种行业小程序开发功能 带完整的搭建教程

小程序开发平台源码系统旨在为用户提供一套高效、稳定、易用的开发工具&#xff0c;帮助用户快速搭建起自己的小程序平台。通过该系统&#xff0c;用户可以轻松实现小程序的定制开发&#xff0c;满足各种行业的需求。同时&#xff0c;还提供了丰富的功能和插件&#xff0c;帮助…

day37 贪心算法part6

738. 单调递增的数字 中等 提示 当且仅当每个相邻位数上的数字 x 和 y 满足 x < y 时&#xff0c;我们称这个整数是单调递增的。 给定一个整数 n &#xff0c;返回 小于或等于 n 的最大数字&#xff0c;且数字呈 单调递增 。 不知道怎么讲思路……以9287举例&#xff0c;…

【蓝桥杯】Excel地址

一.题目描述 二.问题分析 类似于进制转换 //Excel地址 #include <iostream> #include <stack> using namespace std;//const int N1e22; long long n; stack <char> s;int main(int argc, const char * argv[]) {ios::sync_with_stdio(0);cin.tie(0);cout.…

什么是工业边缘网关?工业边缘网关有什么作用?

在数字化和智能化的浪潮下&#xff0c;工业领域正迎来前所未有的变革。其中&#xff0c;工业边缘网关作为这场变革中的重要角色&#xff0c;正逐渐受到人们的关注。那么&#xff0c;什么是工业边缘网关&#xff1f;它如何在工业数字化中发挥作用&#xff1f;今天&#xff0c;就…

虾皮、lazada店铺运营攻略,如何搭建高效、稳定的自养号测评系统

随着电子商务的蓬勃发展&#xff0c;越来越多的人选择在虾皮这样的电商平台上开设店铺&#xff0c;以实现创业梦想。但如何在众多店铺中脱颖而出&#xff0c;成为消费者的首选?本文将为您详细解答“怎么样做好虾皮店铺”&#xff0c;并提供一些实用的运营建议。 一、怎么样做…

F1-score模型评估

什么是F1-score F1-score 是一种用于衡量分类模型性能的指标&#xff0c;它综合了精确度&#xff08;Precision&#xff09;和召回率&#xff08;Recall&#xff09;两个指标。F1-score 的值在 0 和 1 之间&#xff0c;值越接近 1&#xff0c;表示模型的性能越好。在文本分类任…

三八妇女节智慧花店/自动售花机远程视频智能监控解决方案

一、项目背景 国家统计局发布的2023年中国经济年报显示&#xff0c;全年社会消费品零售总额471495亿元&#xff0c;比上年增长7.2%。我国无人零售整体发展迅速&#xff0c;2014年市场规模约为17亿元。无人零售自助终端设备市场规模超过500亿元&#xff0c;年均复合增长率超50%。…

中科数安|防止公司电脑文件资料 \ 数据外泄

中科数安是一家提供企业信息安全解决方案的专业机构&#xff0c;针对防止公司电脑文件资料和数据外泄的问题&#xff0c;可能会提供如下类型的解决方案和服务&#xff1a; 1. **数据加密系统**&#xff1a;通过先进的透明加密技术&#xff0c;实现对公司电脑上的文件进行实时加…

京东获得JD商品详情 API 返回值说明|京东商品采集API接口接入

京东获得JD商品详情 API 返回值说明 item_get-获得JD商品详情 API测试 注册 jd.item_get 公共参数 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff09;secretString是调用密钥api_nameString是API接口名称&#xff08;包括在请求地址中&…

测试一下 Anthropic 宣称超过 GPT-4 的 Claude 3 Opus

测试一下 Anthropic 宣称超过 GPT-4 的 Claude 3 Opus 0. 引言1. 测试 Claude 3 Opus 0. 引言 今天测试一下 Anthropic 发布的 Claude 3 Opus。 3月4日&#xff0c;Anthropic 宣布推出 Claude 3 型号系列&#xff0c;该系列在广泛的认知任务中树立了新的行业基准。该系列包括…

@大学生必看内容!QT创建C++项目,并使用Opencv进行图像处理!

一、创建C项目 二、向C项目部署opencv。详细步骤&#xff1a;查看地址。 避坑&#xff01;&#xff01;

如何判断螺栓已经拧紧?——SunTorque智能扭矩系统

智能扭矩系统-智能拧紧系统-扭矩自动控制系统-SunTorque 螺栓拧紧的标准并非仅仅依赖于螺栓的外观&#xff0c;而是依赖于几个关键因素&#xff0c;包括扭矩、预紧力和材料疲劳等。下面SunTorque智能扭矩系统和大家将详细讨论这些因素&#xff0c;并给出如何判断螺栓是否已经拧…

英语四级开始报名了?大学生如何三个月突破四级【文章底部添加进大学生就业交流群】

目录 一、明确考试内容与要求 二、制定合理的复习计划 三、注重听力和阅读能力的提升 四、加强词汇和语法的积累 五、多做真题和模拟题 英语四级考试&#xff0c;对于大多数大学生来说&#xff0c;是检验英语水平的一个重要标准。随着报名时间的来临&#xff0c;许多同学都…

设计模式(工厂模式)

设计模式&#xff08;工厂模式&#xff09; 一、工厂模式介绍 在工厂模式中&#xff0c;父类决定生成示例的方式&#xff0c;但不决定所要生成的具体的类&#xff0c;具体的处理部分交给子类负责。这样就可以将生成示例的框架和生成示例的类解耦。 二、示例程序 以下示例程…

07 | 行锁功过:怎么减少行锁对性能的影响?

MySQL 的行锁是在引擎层由各个引擎自己实现的。但并不是所有的引擎都支持行锁&#xff0c;比如 MyISAM 引擎就不支持行锁。不支持行锁意味着并发控制只能使用表锁&#xff0c;对于这种引擎的表&#xff0c;同一张表上任何时刻只能有一个更新在执行&#xff0c;这就会影响到业务…

HTML静态网页成品作业(HTML+CSS)——电影网首页网页设计制作(1个页面)

&#x1f389;不定期分享源码&#xff0c;关注不丢失哦 文章目录 一、作品介绍二、作品演示三、代码目录四、网站代码HTML部分代码 五、源码获取 一、作品介绍 &#x1f3f7;️本套采用HTMLCSS&#xff0c;未使用Javacsript代码&#xff0c;共有1个页面。 二、作品演示 三、代…

Flink ExecuteGraph构建源码解析

文章目录 前言ExecutionGraph中的主要抽象概念源码核心代码入口源码核心流程&#xff1a; 前言 在JobGraph构建过程中分析了JobGraph的构建过程&#xff0c;本文分析ExecutionGraph的构建过程。JobManager(JobMaster) 根据 JobGraph 生成 ExecutionGraph。ExecutionGraph是JobG…

keepalived原理以及lvs、nginx跟keeplived的运用

keepalived基础 keepalived的原理是根据vrrp协议&#xff08;主备模式&#xff09;去设定的 vrrp技术相关原理 状态机&#xff1b; 优先级0~255 心跳线1秒 vrrp工作模式 双主双备模式 VRRP负载分担过程 vrrp安全认证&#xff1a;使用共享密匙 keepalived工具介绍 keepal…

Python实现霍德里克-普雷斯科特(Hodrick-Prescott,HP)过滤器模型和UC-ARIMA模型(hpfilter算法)项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档视频讲解&#xff09;&#xff0c;如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 霍德里克-普雷斯科特&#xff08;Hodrick-Prescott, HP&#xff09;过滤器模型&#xff1a; HP滤波器是…