C++设计模式-创建型设计模式

设计模式

设计模式是什么

设计模式是指在软件开发中,经过验证的,用于解决在特定环境下,重复出现的,特定问题的解决方案;其实就是解决问题的固定套路。但是要慎用设计模式,有一定的工程代码量之后用它比较好。

设计模式怎么来的

满足设计原则后,然后慢慢迭代出来的

设计模式解决了什么问题?

前提:具体需求既有稳定点,又有变化点。全是稳定点,或者全是变化点(游戏开发,脚本语言)都不要用。我们期望修改少量的代码,就可以适应需求的变化。
一个比喻:整洁的房间,好动猫,怎么保证房间的整洁?
就是把猫关在一个笼子里,这个猫就是我们需求,把猫关在笼子中,就是设计模式。

设计模式的基础

面向对象的思想

封装:主要是隐藏实现细节,实现模块化
继承:无需修改原有类的情况下通过继承实现对功能的扩展
多态:静态多态:函数重载。
多态:动态多态:继承中虚函数重写。
这个就是多态:
在这里插入图片描述

设计原则

依赖倒置

  • 高层模块不应该依赖低层模块,两者都应该依赖抽象;
  • 抽象不应该依赖具体实现,具体实现应该依赖于抽象;
    在这里插入图片描述
  • 自动驾驶系统公司是高层,汽车生产厂商为低层,它们不应该互相依赖,一方变动另一方也会跟着变动;而应该抽象一个自动驾驶行业标准,高层和低层都依赖它;这样以来就解耦了两方的变动;自动驾驶系统、汽车生产厂商都是具体实现,它们应该都依赖自动驾驶行业标准(抽象);接口的使用者不要依赖具体的实现。要依赖具体的接口。

开放封闭
主要针对封装和多态
一个类应该对扩展(组合和继承)开放,对修改关闭;

面向接口
主要针对封装

  • 不将变量类型声明为某个特定的具体类,而是声明为某个接口;
  • 客户程序无需获知对象的具体类型,只需要知道对象所具有的接口;
  • 减少系统中各部分的依赖关系,从而实现“高内聚、松耦合”的类型设计方案;

封装变化点
主要针对封装和多态
将稳定点和变化点分离,扩展修改变化点;让稳定点和变化点的实现层次分离;

单一职责
一个类应该仅有一个引起它变化的原因;

里氏替换
主要针对多态
子类型必须能够替换掉它的父类型;主要出现在子类覆盖父类实现,原来使用父类型的程序可能出现错误;覆盖了父类方法却没有实现父类方法的职责;

接口隔离

  • 不应该强迫客户依赖于它们不用的方法;
  • 一般用于处理一个类拥有比较多的接口,而这些接口涉及到很多职责;
  • 客户端不应该依赖它不需要的接口。一个类对另一个类的依赖应该建立在最小的接口上。

组合优于继承
继承耦合度高,组合耦合度低;

最小知道原则
对这个类知道的越少越好,只要知道接口就行

如何学习设计模式

明确目的

新手:在现有设计模式的基础上,扩展代码
老手:做功能抽象时,如何选择设计模式

学习步骤

该设计模式解决了什么问题?

  • 稳定点
  • 变化点

该设计模式的代码结构是什么?

符合哪些设计原则?

如何在上面扩展代码?

该设计模式有哪些典型应用场景?

  • 联系工作场景
  • 开源框架

设计模式-模块方法

第一个设计模式:模块方法

定义

定义一个操作中的算法的骨架 ,而将一些步骤延迟到子类中。Template Method使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤。 ——《 设计模式》 GoF
背景:
某个品牌动物园,有一套固定的表演流程,但是其中有若干个表演子流程可创新替换,以尝试迭代更新表演流程;这个和上面定义差不多。

解决问题

解决问题:稳定点就是算法骨架,变化点就是重定义该算法的某些特定步骤,子流程需要变化。

代码结构

  • 基类中有骨架流程接口,上面代码中就是那个show()函数中,有show1(),show2()
  • 所有子流程对子类开放并且是虚函数(protected)
  • 多态使用方式,用基类指针new一个扩展类

有虚函数,并且被protected方法修饰,90%是我们的模板方法。

我们来实现这个某个品牌动物园,有一套固定的表演流程,但是其中有若干个表演子流程可创新替换,以尝试迭代更新表演流程;这个和上面定义差不多。

来看一个代码对比,第一个代码是没有设计模式的,第二个代码是用了设计模式的:

#include <iostream>
using namespace std;

// 设计原则
// 1. 设计原则演变过来的  2.符合设计原则的代码,只需要修改少量代码就可以演变成设计模式
// 接口隔离原则  1. 类封装 权限限定词(private,public....)来实现 2. 类与类依赖 接口(依赖注入)
// 最小知道原则
// 破坏了哪些设计原则:
// 单一职责(变化方向) 封装
// 开闭原则 对扩展开放 对修改关闭
// 扩展方式:继承,多态组合
class ZooShow {
public:
    ZooShow(int type = 1) : _type(type) {}

public:
    void Show() {
        if (Show0())
            PlayGame();
        Show1();
        Show2();
        Show3();
    }

private://不能让其选择show0(),show1(),show2().
    void PlayGame() {
        cout << "after Show0, then play game" << endl;
    }

    bool Show0() {
        if (_type == 1) {
            // 
            return true;
        } else if (_type == 2 ) {
            //  ...
        } else if (_type == 3) {

        }
        cout << _type << " show0" << endl;
        return true;
    }

    void Show1() {
        if (_type == 1) {
            cout << _type << " Show1" << endl;
        } else if (_type == 2) {
            cout << _type << " Show1" << endl;
        } else if (_type == 3) {

        }
    }

    void Show2() {
        if (_type == 20) {
            
        }
        cout << "base Show2" << endl;
    }

    void Show3() {
        if (_type == 1) {
            cout << _type << " Show1" << endl;
        } else if (_type == 2) {
            cout << _type << " Show1" << endl;
        }
    }
private:
    int _type;
};


int main () {
    ZooShow *zs = new ZooShow(1);
    zs->Show();
    return 0;
}

用了设计模式

#include <iostream>
using namespace std;

// 开闭
class ZooShow {
public:
    void Show() {
        // 如果子表演流程没有超时的话,进行一个中场游戏环节;如果超时,直接进入下一个子表演流程
        if (Show0())
            PlayGame();
        Show1();
        Show2();
        Show3();
    }
    
private:
    void PlayGame() {
        cout << "after Show0, then play game" << endl;
    }
    bool expired;
    // 对其他用户关闭,但是子类开放的
protected:
    virtual bool Show0() {
        cout << "show0" << endl;
        if (! expired) {
            return true;
        }
        return false;
    }
    virtual void Show2() {
        cout << "show2" << endl;
    }
    virtual void Show1() {

    }
    virtual void Show3() {

    }
};

// 框架
// 模板方法模式
class ZooShowEx10 : public ZooShow {
protected:
    virtual void Show0() {
        if (! expired) {
            return true;
        }
        return false;
    }
}

class ZooShowEx1 : public ZooShow {
protected:
    virtual bool Show0() {
        cout << "ZooShowEx1 show0" << endl;
        if (! expired) { // 里氏替换
            return true;
        }
        return false;
    }
    virtual void Show2(){
        cout << "show3" << endl;
    }
};

class ZooShowEx2 : public ZooShow {
protected:
    virtual void Show1(){
        cout << "show1" << endl;
    }
    virtual void Show2(){
        cout << "show3" << endl;
    }
};

class ZooShowEx3 : public ZooShow {
protected:
    virtual void Show1(){
        cout << "show1" << endl;
    }
    virtual void Show3(){
        cout << "show3" << endl;
    }
    virtual void Show4() {
        //
    }
};
/*
*/
int main () {
    ZooShow *zs = new ZooShowEx10; // 晚绑定还是早绑定
    // ZooShow *zs1 = new ZooShowEx1;
    // ZooShow *zs2 = new ZooShowEx2;
    zs->Show();
    return 0;
}

符合那些原则

单一职责
开闭
依赖倒置

  • 子类扩展时,需要依赖基类的虚函数实现
  • 使用者只依赖接口

封装变化点(protected)
接口隔离
最小知道原则
对于用户我们只需要知道show(),然后zs->show()就可以了。

如何扩展

也就是这一块

class ZooShowEx1 : public ZooShow {
protected:
    virtual bool Show0() {
        cout << "ZooShowEx1 show0" << endl;
        if (! expired) { // 里氏替换
            return true;
        }
        return false;
    }
    virtual void Show2(){
        cout << "show3" << endl;
    }
};

实现子类继承基类,复写子流程
通过多态调用方式使用

总结

要点

  • 最常用的设计模式,子类可以复写父类子流程,使父类的骨架流程丰富;
  • 反向控制流程的典型应用;
  • 父类 protected 保护子类需要复写的子流程;这样子类的子流程
  • 只能父类来调用;

本质
通过固定算法骨架来约束子类的行为;
结构图
在这里插入图片描述

设计模式-观察者模式

定义

对象间的一种一对多(变化)的依赖关系,以便当一个对象(Subject)的状态发生改变时,所有依赖于它的对象都得到通知并自动更新。 ——《 设计模式》 GoF

解决问题

稳定性:“—”对“多”的依赖关系,“一”变化“多”跟着变化

变化点:“多”增加,“多”减少

代码结构

背景:
气象站发布气象资料给数据中心,数据中心经过处理,将气象信息更新到两个不同的显示终端(A 和B);一是数据中心的数据,多是所有的中断的数据都要变化

没有使用设计模式的时候:问题就是每次增加终端都要修改代码


class DisplayA {
public:
    void Show(float temperature);
};

class DisplayB {
public:
    void Show(float temperature);
};

class DisplayC {
public:
    void Show(float temperature);
}

class WeatherData {
};

class DataCenter {
public:
    void TempNotify() {
        DisplayA *da = new DisplayA;
        DisplayB *db = new DisplayB;
        DisplayC *dc = new DisplayC;
        // DisplayD *dd = new DisplayD;
        float temper = this->CalcTemperature();//计算数据
        da->Show(temper);//跟新数据
        db->Show(temper);
        dc->Show(temper);
        dc->Show(temper);
        //问题就是每次增加终端都要修改代码
    }
private:
    float CalcTemperature() {
        WeatherData * data = GetWeatherData();
        // ...
        float temper/* = */;
        return temper;
    }
    WeatherData * GetWeatherData(); // 不同的方式
};

int main() {
    DataCenter *center = new DataCenter;//数据中心
    center->TempNotify();
    return 0;
}

使用设计模式:具体中断的改变不能影响我们的接口。应对稳定点,抽象。应对变化点,扩展(继承和组合)
对于一对多,一就是DataCenter,而多就是在DataCenter中定义一个list。

// 应对稳定点,抽象
// 应对变化点,扩展(继承和组合)
class DataCenter {//一
public:
    void Attach(IDisplay * ob) {//增加终端,用户可以加入
        //
    }
    void Detach(IDisplay * ob) {//减少终端
        //
    }
    void Notify() {//数据变化,通知各个终端,一变化,多就变化
        float temper = CalcTemperature();
        for (auto iter : obs) {
            iter.Show(temper);
        }
    }

// 接口隔离
private:
    WeatherData * GetWeatherData();

    float CalcTemperature() {
        WeatherData * data = GetWeatherData();
        // ...
        float temper/* = */;
        return temper;
    }
    std::list<IDisplay*> obs;//终端,这个就是多
};

完整代码:

#include <list>
#include <algorithm>
using namespace std;
//
class IDisplay {//显示每一个终端
public:
    virtual void Show(float temperature) = 0;
    virtual ~IDisplay() {}
};

class DisplayA : public IDisplay {
public:
    virtual void Show(float temperature) {
        cout << "DisplayA Show" << endl;
    }
private:
    void jianyi();
};

class DisplayB : public IDisplay{
public:
    virtual void Show(float temperature) {
        cout << "DisplayB Show" << endl;
    }
};

class DisplayC : public IDisplay{
public:
    virtual void Show(float temperature) {
        cout << "DisplayC Show" << endl;
    }
};

class DisplayD : public IDisplay{
public:
    virtual void Show(float temperature) {
        cout << "DisplayC Show" << endl;
    }
};

class WeatherData {
};

// 应对稳定点,抽象
// 应对变化点,扩展(继承和组合)
class DataCenter {
public:
    void Attach(IDisplay * ob) {//增加终端,用户可以加入
        //
    }
    void Detach(IDisplay * ob) {//减少终端
        //
    }
    void Notify() {//数据变化,通知各个终端
        float temper = CalcTemperature();
        for (auto iter : obs) {
            iter.Show(temper);
        }
    }

// 接口隔离
private:
    WeatherData * GetWeatherData();

    float CalcTemperature() {
        WeatherData * data = GetWeatherData();
        // ...
        float temper/* = */;
        return temper;
    }
    std::list<IDisplay*> obs;//终端
};

int main() {
    // 单例模式
    DataCenter *center = new DataCenter;
    // ... 某个模块(实际上都是在其他文件中)
    IDisplay *da = new DisplayA();
    center->Attach(da);

    // ...(实际上都是在其他文件中)
    IDisplay *db = new DisplayB();
    center->Attach(db);
    (实际上都是在其他文件中)
    IDisplay *dc = new DisplayC();
    center->Attach(dc);

    center->Notify();
    
    //-----
    center->Detach(db);
    center->Notify();


    //....
    center->Attach(dd);

    center->Notify();
    return 0;
}

补充:单例(Singleton)模式的定义:指一个类只有一个实例,且该类能自行创建这个实例的一种模式。

符合哪些设计原则

面向接口编程
接口隔离

  • 类与类依赖在一个接口(就是那个list)
  • 容器存储接口

封装变化点

  • attach(增加终端)
  • detach(减少终端)

如何扩展

继承实现接口
调用attach
调用detach
就是这样:

class DisplayD : public IDisplay{
public:
    virtual void Show(float temperature) {
        cout << "DisplayC Show" << endl;
    }
};

 center->Attach(dd);

 center->Notify();

总结

要点

  • 观察者模式使得我们可以独立地改变目标与观察者,从而使二者之间的关系松耦合;
  • 观察者自己决定是否订阅通知,目标对象并不关注谁订阅了;
  • 观察者不要依赖通知顺序,目标对象也不知道通知顺序;
  • 常用在基于事件的ui框架中,也是 MVC 的组成部分;
  • 常用在分布式系统中、actor框架中;
    本质
    触发联动
    结构图
    在这里插入图片描述

设计模式-策略模式

定义

定义一系列算法,把它们一个个封装起来,并且使它们可互相替换。该模式使得算法可独立于使用它的客户程序而变化。——《设计模式》 GoF

解决问题

稳定点

  • 客户程序与算法的调用关系

变化点

  • 新加算法
  • 算法内容改变

客户只需要调用就行,不需要知道那个算法

代码结构

某商场节假日有固定促销活动,为了加大促销力度,现提升国庆节促销活动规格;稳定点就是这个促销活动,改变点就是这些具体的活动折扣啥的。
也就是策略模式用来消除if-else
没有设计模式的代码:

enum VacationEnum {
	VAC_Spring,
    VAC_QiXi,
	VAC_Wuyi,
	VAC_GuoQing,
    VAC_ShengDan,
};

class Promotion {
    VacationEnum vac;
public:
    double CalcPromotion(){
        if (vac == VAC_Spring {
            // 春节
        }
        else if (vac == VAC_QiXi) {
            // 七夕
        }
        else if (vac == VAC_Wuyi) {
            // 五一
        }
		else if (vac == VAC_GuoQing) {
			// 国庆
		}
        else if (vac == VAC_ShengDan) {

        }
     }
    
};

加人了设计模式:
其中
稳定点:抽象去解决它(调用关系)
变化点:扩展(继承和组合)去解决它

class Context {

};

// 稳定点:抽象去解决它
// 变化点:扩展(继承和组合)去解决它
class ProStategy {
public:
    virtual double CalcPro(const Context &ctx) = 0;
    virtual ~ProStategy(); 
};
// cpp
class VAC_Spring : public ProStategy {
public:
    virtual double CalcPro(const Context &ctx){}
};
// cpp
class VAC_QiXi : public ProStategy {
public:
    virtual double CalcPro(const Context &ctx){}
};
class VAC_QiXi1  : public VAC_QiXi {
public:
    virtual double CalcPro(const Context &ctx){}
};
// cpp
class VAC_Wuyi : public ProStategy {
public:
    virtual double CalcPro(const Context &ctx){}
};
// cpp
class VAC_GuoQing : public ProStategy {
public:
    virtual double CalcPro(const Context &ctx){}
};

class VAC_Shengdan : public ProStategy {
public:
    virtual double CalcPro(const Context &ctx){}
};

class Promotion {
public:
    Promotion(ProStategy *sss) : s(sss){}
    ~Promotion(){}
    double CalcPromotion(const Context &ctx){
        return s->CalcPro(ctx);
    }
private:
    ProStategy *s;//这就是一种依赖注入的方式
};

int main () {
    Context ctx;
    ProStategy *s = new VAC_QiXi1();
    Promotion *p = new Promotion(s);
    p->CalcPromotion(ctx);
    return 0;
}

设计原则

接口隔离

  • 依赖注入(*s就是依赖注入)
    class Promotion {
    public:
        Promotion(ProStategy *sss) : s(sss){}
        ~Promotion(){}
        double CalcPromotion(const Context &ctx){
            return s->CalcPro(ctx);
        }
    private:
        ProStategy *s;//依赖注入的方式
    };
    
  • 解决通过一个接口解决两个类的依赖

面向接口编程
开闭原则

如何扩展代码

写一个接口,然后依赖注入的方式调用它

class VAC_QiXi1: public ProStategy {
public:
    virtual double CalcPro(const Context &ctx){}
};

 Context ctx;
 ProStategy *s = new VAC_QiXi1();
 Promotion *p = new Promotion(s);
 p->CalcPromotion(ctx);

总结

要点

  • 策略模式提供了一系列可重用的算法,从而可以使得类型在运行时方便地根据需要在各个算法之间进行切换;
  • 策略模式消除了条件判断语句;也就是在解耦合;

本质
分离算法,选择实现;
结构图
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Hdfs小文件治理策略以及治理经验

小文件是 Hadoop 集群运维中的常见挑战&#xff0c;尤其对于大规模运行的集群来说可谓至关重要。如果处理不好&#xff0c;可能会导致许多并发症。Hadoop集群本质是为了TB,PB规模的数据存储和计算因运而生的。为啥大数据开发都说小文件的治理重要&#xff0c;说HDFS 存储小文件…

Python字符串常用方法(全网最细,仅此一份)

🥇作者简介:CSDN内容合伙人、新星计划第三季Python赛道Top1 🔥本文已收录于Python系列专栏: 👉Python从入门到精通 💬订阅专栏后可私信博主进入Python学习交流群,进群可领取Python180G全栈视频教程以及Python相关电子书合集 😊私信未回可以加V:hacker0327 备注P…

Word文件后缀

Word文件后缀 .docx文件为Microsoft Word文档后缀名&#xff0c;基于XML文件格式 .dotm为Word启用了宏的模板 .dotx为Word模板 .doc为Word97-2003文档&#xff0c;二进制文件格式 参考链接 Word、Excel 和 PowerPoint 的文件格式参考 Learn Microsoft

u盘格式化后电脑读不出来怎么办?u盘格式化的东西还能恢复吗

随着科技的快速发展&#xff0c;U盘已成为我们日常生活和工作中不可或缺的数据存储工具。然而&#xff0c;有时我们可能会遇到U盘格式化后电脑无法读取的情况&#xff0c;或是误格式化导致重要数据丢失。面对这些问题&#xff0c;我们该如何应对&#xff1f;本文将为您详细解答…

C语言 main( ) 函数的指针数组形参是怎么回事?

一、问题 在使⽤⼀些开发⼯具⽣成C语⾔⽂件时&#xff0c;主函数 mian( ) 中会有参数&#xff0c;这个参数到底是怎么回事⼉呢&#xff1f; 二、解答 mian( ) 称为主函数&#xff0c;是所有程序运⾏的⼊口。 mian( ) 函数是由系统调⽤的&#xff0c;当处于操作命令状态下&…

解锁学术语言:掌握论文释义工具的高效使用技巧

研究论文是一份书面文件&#xff0c;其中包括对特定主题的论点、想法和观点的概述。释义至关重要&#xff0c;因为它可以为您的工作增添意义和价值。教育释义的核心目的是增加你的写作的价值&#xff0c;同时考虑其他作家的观点和发现&#xff0c;并建立与你的主题的相关性。通…

恶补《操作系统》5_1——王道学习笔记

5设备管理 5.1_1 I-O设备的概念和分类 1、什么是I-O设备 输入/输出&#xff1a;I/O设备就是可以将数据输入到计算机&#xff0c;或者可以接收计算机输出数据的外部设备&#xff0c;属于计算机中的硬件部件。 2、按使用特性分类 人机交互的外部设备存储设备网络通信设备 3、…

k8s Dashboard 运维维护记录

k8s Dashboard 运维维护记录 k8s Dashboard 运维维护记录 Q1&#xff1a;需要使用firefox浏览器访问 提示了证书错误NET::ERR_CERT_INVALID&#xff0c;原因是由于物理机的浏览器证书不可用 需要注意的是&#xff0c;若提示“连接不安全”的警告时&#xff0c;点击“高级”…

计算机的翻译(编译和链接)过程

&#x1f381;个人主页&#xff1a;我们的五年 &#x1f50d;系列专栏&#xff1a;C语言基本概念 &#x1f337;追光的人&#xff0c;终会万丈光芒 &#x1f389;欢迎大家点赞&#x1f44d;评论&#x1f4dd;收藏⭐文章 目录 &#x1f697;1.翻译环境和运行环境&#xff1…

AI大模型探索之路-训练篇12:语言模型Transformer库-Datasets组件实践

系列篇章&#x1f4a5; AI大模型探索之路-训练篇1&#xff1a;大语言模型微调基础认知 AI大模型探索之路-训练篇2&#xff1a;大语言模型预训练基础认知 AI大模型探索之路-训练篇3&#xff1a;大语言模型全景解读 AI大模型探索之路-训练篇4&#xff1a;大语言模型训练数据集概…

深入理解 LinkedList 及底层源码分析

LinkedList 是基于链表结构的一种 List&#xff0c;在分析 LinkedList 源码前我们先对对链表结构做一个简单的了解。 一、链表的概念 链表是由一系列非连续的节点组成的存储结构&#xff0c;简单分下类的话&#xff0c;链表又分为_单向链表和双向链表&#xff0c;而单向 / 双…

函数之对决!!:数学函数 VS C++函数

前言 有人问过我&#xff0c;C里的函数是否跟我们数学里的函数一样&#xff1f;于是&#xff0c;我就写下了这篇文章。 一、数学函数 1、一次函数 一次函数&#xff0c;也称为线性函数&#xff0c;是数学中函数的一种&#xff0c;通常表示为ykxb&#xff08;其中k和b是常数&am…

HR面试测评,招聘市场部主管的人才测评方案

人才测评有时候也叫岗位胜任力测评&#xff0c;也有叫综合素质或综合能力测评&#xff0c;其目的都是为了寻找人岗匹配&#xff0c;找到适合这个岗位的人才&#xff0c;为企业创造最大化的价值。企业是一个平台&#xff0c;也是个人实现自我价值的途径&#xff0c;实际上人才测…

3GPP官网下载协议步骤

1.打开官网 https://www.3gpp.org/ 2.点击 3.在界面选择要找的series&#xff0c;跳转到查找界面 以V2X通信协议为例&#xff0c;论文中通常会看到许多应用&#xff1a; [7] “Study on evaluation methodology of new Vehicle-to-Everything (V2X) use cases for LTE and NR…

Mac 更新 Homebrew软件包时提示 zsh: command not found: brew 错误

问题 通过Mac电脑更新Homebrew软件包时出现如下错误&#xff1a; xxxxxxxpiaodeMacBook-Pro ~ % brew update zsh: command not found: brew解决方案 在命令行输入如下指令&#xff1a; /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/H…

基于免疫粒子群算法的考虑负荷需求相应的热电联供系统优化调度(MATLAB实现)

1.研究背景 随着“双碳”战略的提出&#xff0c;各种分布式能源的开发和利用收到越来越多的重视。冷热电联供(Combined Cooling Heating and Power, CCHP)系统在发电的同时可以将燃气轮机产生的废热用于制热或制冷&#xff0c;实现能量的梯级利用&#xff0c;并减少系统的污染气…

C++进阶-----继承

1、继承的概念和定义 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段&#xff0c;它允许程序员在保持原有类特性的基础上进行扩展&#xff0c;增加功能&#xff0c;这样产生新的类&#xff0c;称派生类。继承呈现了面向对象 程序设计的层次结构&#xf…

【Java从入门到精通】Java 流(Stream)、文件(File)和IO

Java.io 包几乎包含了所有操作输入、输出需要的类。所有这些流类代表了输入源和输出目标。 Java.io 包中的流支持很多种格式&#xff0c;比如&#xff1a;基本类型、对象、本地化字符集等等。 一个流可以理解为一个数据的序列。输入流表示从一个源读取数据&#xff0c;输出流…

[每日AI·0501]GitHub 版 Devin,Transformer的强力挑战者 Mamba,Sora 制作细节与踩坑,OpenAI 记忆功能

AI 资讯 国资委&#xff1a;加快人工智能等新技术与制造全过程、全要素深度融合GitHub版 Devin 上线&#xff0c;会打字就能开发应用&#xff0c;微软 CEO&#xff1a;重新定义 IDE在12个视频理解任务中&#xff0c;Mamba 先打败了 TransformerSora 会颠覆电影制作吗&#xff…

无极花 专业韩语 朝鲜语网站建设

无极花 https://www.wujihua.com 无极花建站 - 始于2016年&#xff0c;专业的韩语、朝鲜语网站开发团队&#xff0c;从事网页设计、网站开发、网站托管、网站维护、网站推广、搜索引擎SEO优化等服务。