C++学习笔记(十六)

一、多态

1. 多态的基本概念

多态是C++面向对象三大特性之一

多态分为两类

1. 静态多态:函数重载 和 运算符重载属于静态多态,复用函数名

2. 动态多态:派生类和虚函数实现运行时多态

静态多态和动态多态区别:

1. 静态多态的函数地址早绑定 —— 编译阶段确定函数地址

2. 动态多态的函数地址晚绑定 —— 运行阶段确定函数地址

#include <iostream>using namespace std;// 动物类
class Animal
{
public:// 虚函数virtual void speak(){cout << "动物在叫......" << endl;}
};// 猫类
class Cat :public Animal
{
public:void speak(){cout << "小猫在喵喵叫......" << endl;}
};// 狗类
class Dog :public Animal
{
public:void speak(){cout << "小狗在汪汪叫......" << endl;}
};// 执行叫的函数
// 地址早绑定 在编译阶段就确定了函数地址
// 如果想执行让猫叫或者让狗叫,那么这个函数的地址就不能提前绑定,需要在运行阶段进行绑定,地址晚绑定
void doSpeak(Animal& animal) // Animal& animal = cat;父类的引用指向子类的对象
{animal.speak();
}void test()
{Cat cat;doSpeak(cat);Dog dog;doSpeak(dog);
}
int main(int argc, char* argv[])
{test();return 0;
}

动态多态满足的条件:

1. 有继承关系

2. 子类重写父类的虚函数

动态多态使用:父类的指针或者引用指向子类对象

重写:函数返回值类型、函数名、参数列表完全一致

重载:函数的参数列表不同

2. 多态的原理

在定义了虚函数的类中,都会有一个虚函数表指针,指向该类的虚函数表,表内记录虚函数的地址

当派生类继承基类时,会继承基类的虚函数表指针,指向基类的虚函数表

如果在派生类中实现了重写,先将基类虚表内容拷贝一份至派生类的虚表当中(派生类的虚表是自己生成的,这两个虚表的地址不一样),然后将重写的虚函数的地址放入虚表的对应位置。

3. 多态案例一:计算机类

案例描述:

分别应用普通写法和多态技术,设计实现两个操作数进行运算的计算器

多态的优点:

1. 代码组织结构清晰

2. 可读性强

3. 利于前期和后期的扩展以及维护

普通实现:

#include <iostream>
#include <string>using namespace std;class Calculator
{
public:double m_num1;double m_num2;double getResult(string oper){if (oper == "+")return m_num1 + m_num2;else if(oper == "-")return m_num1 - m_num2;else if (oper == "*")return m_num1 * m_num2;else if (oper == "/")return m_num1 / m_num2;}
};void test()
{Calculator c;c.m_num1 = 20;c.m_num2 = 3.3;cout << c.m_num1 << " + " << c.m_num2 << " = " << c.getResult("+") << endl;cout << c.m_num1 << " - " << c.m_num2 << " = " << c.getResult("-") << endl;cout << c.m_num1 << " * " << c.m_num2 << " = " << c.getResult("*") << endl;cout << c.m_num1 << " / " << c.m_num2 << " = " << c.getResult("/") << endl;
}
int main(int argc, char* argv[])
{test();return 0;
}

如果想扩展新的功能,需要修改源码

在真实的开发中,提供开闭原则

开闭原则:对扩展进行开放,对修改进行关闭

#include <iostream>
#include <string>using namespace std;// 实现计算器基类
class BaseCalculator
{
public:double m_num1;double m_num2;virtual double getResult(){return 0;}
};// 加法计算器类
class AddCalculator : public BaseCalculator
{
public:double getResult(){return m_num1 + m_num2;}
};// 减法计算器类
class SubCalculator : public BaseCalculator
{
public:double getResult(){return m_num1 - m_num2;}
};// 乘法计算器类
class MulCalculator : public BaseCalculator
{
public:double getResult(){return m_num1 * m_num2;}
};// 除法计算器类
class DivCalculator : public BaseCalculator
{
public:double getResult(){return m_num1 / m_num2;}
};void test()
{// 多态使用条件// 父类指针或者引用指向子类对象// 加法运算BaseCalculator *calculator = new AddCalculator;calculator->m_num1 = 20;calculator->m_num2 = 3.3;cout << calculator->m_num1 << " + " << calculator->m_num2 << " = " << calculator->getResult() << endl;// 堆区数据手动开辟手动释放delete calculator;// 减法运算calculator = new SubCalculator;calculator->m_num1 = 20;calculator->m_num2 = 3.3;cout << calculator->m_num1 << " - " << calculator->m_num2 << " = " << calculator->getResult() << endl;delete calculator;// 乘法运算calculator = new MulCalculator;calculator->m_num1 = 20;calculator->m_num2 = 3.3;cout << calculator->m_num1 << " * " << calculator->m_num2 << " = " << calculator->getResult() << endl;delete calculator;// 除法运算calculator = new DivCalculator;calculator->m_num1 = 20;calculator->m_num2 = 3.3;cout << calculator->m_num1 << " / " << calculator->m_num2 << " = " << calculator->getResult() << endl;delete calculator;
}
int main(int argc, char* argv[])
{test();return 0;
}

4. 纯虚函数和抽象类

在多态中,通常父类中虚函数的实现是毫无意义的,主要都是调用子类重写的内容

因此可以将虚函数改为纯虚函数

纯虚函数语法:virtual 返回值类型 函数名 (参数列表)= 0;

当类中有了纯虚函数,这个类也称为抽象类

抽象类的特点:

1. 无法实例化对象

2. 子类必须重写抽象类中的纯虚函数,否则也属于抽象类

#include <iostream>using namespace std;class Base
{
public:virtual void func() = 0;
};class Son1 : public Base
{void func(){cout << "已对父类的的纯虚函数进行重写..." << endl;}
};class Son2 : public Base
{
public:};void test()
{// 无法对抽象类进行实例化// Base b;Base* ptr1 = new Son1;ptr1->func();// 子类必须重写抽象类中的纯虚函数,否则也属于抽象类// Base* ptr2 = new Son2;
}int main(int argc, char* argv[])
{test();return 0;
}

5. 多态案例二:制作饮品

案例描述:制作饮品的大致流程为:煮水 -> 冲泡(咖啡、茶叶) -> 倒入杯中 -> 加入辅料(糖、柠檬)

利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶

#include <iostream>using namespace std;class AbstractDrinking
{
public:void Boil(){cout << "煮水中..." << endl;}virtual void Brew() = 0;void PourInCup(){cout << "正在倒入杯中..." << endl;}virtual void PutSomething() = 0;void Done(){cout << "制作完成..." << endl;}void makeDrink(){Boil();Brew();PourInCup();PutSomething();Done();}
};class Coffee : public AbstractDrinking
{
public:void Brew(){cout << "正在冲泡咖啡..." << endl;}void PutSomething(){cout << "正在加入糖..." << endl;}
};class Tea : public AbstractDrinking
{
public:void Brew(){cout << "正在冲泡茶叶..." << endl;}void PutSomething(){cout << "正在加入枸杞..." << endl;}
};void doWork(AbstractDrinking *abs)
{abs->makeDrink();delete abs;
}void test()
{// 制作咖啡doWork(new Coffee);cout << "-------------------" << endl;// 制作茶doWork(new Tea);
}
int main(int argc, char* argv[])
{test();return 0;
}

6. 虚析构和纯虚析构

多态使用时,如果子类中有属性开辟到了堆区,那么父类指针在释放时无法调用到子类的析构代码

解决方式:将父类中的析构函数改为虚析构或者纯虚析构

虚析构和纯虚析构的共性:

        1. 可以解决父类指针释放子类对象

        2. 都需要有具体的函数实现

虚析构和纯虚析构的区别:

        1. 如果时纯虚析构,该类属于抽象类,无法实例化对象

虚析构语法:virtual ~类名( ){ }

纯虚析构语法:需要声明和实现

                      virtual ~类名() = 0;

                      类名::~类名( ){ }

#include <iostream>using namespace std;class Base
{
public:virtual void func() = 0;Base(){cout << "基类的构造函数已调用..." << endl;}~Base(){cout << "基类的析构函数已调用..." << endl;}
};class Son : public Base
{
public:void func(){cout << "派生类中重写的纯虚函数已调用..." << endl;}Son(){cout << "派生类的构造函数已调用..." << endl;}~Son(){cout << "派生类的析构函数已调用..." << endl;}
};void test()
{Base* ptr = new Son;ptr->func();delete ptr;
}int main(int argc, char* argv[])
{test();return 0;
}

从运行结果可以看出,父类指针在析构时,不会调用子类中的析构函数,如果子类中有堆区属性,就会出现内存泄漏的问题

利用虚析构可以解决父类指针释放子类对象时不干净的问题

#include <iostream>using namespace std;class Base
{
public:virtual void func() = 0;Base(){cout << "基类的构造函数已调用..." << endl;}virtual ~Base(){cout << "基类的析构函数已调用..." << endl;}
};class Son : public Base
{
public:void func(){cout << "派生类中重写的纯虚函数已调用..." << endl;}Son(){cout << "派生类的构造函数已调用..." << endl;}~Son(){cout << "派生类的析构函数已调用..." << endl;}
};void test()
{Base* ptr = new Son;ptr->func();delete ptr;
}int main(int argc, char* argv[])
{test();return 0;
}

纯虚析构也可以解决这个问题,但是要注意,纯虚析构不同于纯虚函数,纯虚析构需要类内声明类外实现

#include <iostream>using namespace std;class Base
{
public:virtual void func() = 0;Base(){cout << "基类的构造函数已调用..." << endl;}virtual ~Base() = 0;
};
Base::~Base()
{cout << "基类的纯虚析构函数已调用..." << endl;
}class Son : public Base
{
public:void func(){cout << "派生类中重写的纯虚函数已调用..." << endl;}Son(){cout << "派生类的构造函数已调用..." << endl;}~Son(){cout << "派生类的析构函数已调用..." << endl;}
};void test()
{Base* ptr = new Son;ptr->func();delete ptr;
}int main(int argc, char* argv[])
{test();return 0;
}

总结:

1. 虚析构或纯虚析构就是用来解决通过父类指针释放子类对象

2. 如果子类中没有堆区数据,可以不写为虚析构或纯虚析构

3. 拥有纯虚析构函数的类也属于抽象类

7. 多态案例三:电脑组装

案例描述:

电脑主要组成部件为CPU(用于计算),显卡(用于显示),内存条(用于存储)

将每个零件封装出抽象类,并且提供不同的厂商生产不同的零件,例如Intel厂商和Lenovo厂商

创建电脑类提供让电脑工作的函数,并且调用每个零件工作的接口

测试时组装三台不同的电脑进行工作

#include <iostream>using namespace std;class CPU
{
public:virtual void calculate() = 0;
};class VideoCard
{
public:virtual void show() = 0;
};class Memory
{
public:virtual void store() = 0;
};class IntelCPU : public CPU
{
public:void calculate(){cout << "计算能力:10" << endl;}
};class IntelVideoCard : public VideoCard
{
public:void show(){cout << "显示能力:7" << endl;}
};class IntelMemory : public Memory
{
public:void store(){cout << "存储能力:8" << endl;}
};class LenovoCPU : public CPU
{
public:void calculate(){cout << "计算能力:9" << endl;}
};class LenovoVideoCard : public VideoCard
{
public:void show(){cout << "显示能力:6" << endl;}
};class LenovoMemory : public Memory
{
public:void store(){cout << "存储能力:9" << endl;}
};class Computer
{
public:Computer(CPU* CPU, VideoCard* vc, Memory* mem){m_CPU = CPU;m_vc = vc;m_mem = mem;}void work(){m_CPU->calculate();m_vc->show();m_mem->store();}~Computer(){if (m_CPU != NULL){delete m_CPU;m_CPU = NULL;}if (m_vc != NULL){delete m_vc;m_vc = NULL;}if (m_mem != NULL){delete m_mem;m_mem = NULL;}}
private:CPU* m_CPU;VideoCard* m_vc;Memory* m_mem;
};void test()
{// 第一台电脑cout << "--------第一台电脑--------" << endl;CPU* First_CPU = new IntelCPU;VideoCard* First_VideoCard = new IntelVideoCard;Memory* First_Memory = new IntelMemory;Computer* c1 = new Computer(First_CPU, First_VideoCard, First_Memory);c1->work();delete c1;// 第二台电脑cout << "--------第二台电脑--------" << endl;CPU* Second_CPU = new LenovoCPU;VideoCard* Second_VideoCard = new LenovoVideoCard;Memory* Second_Memory = new LenovoMemory;Computer* c2 = new Computer(Second_CPU, Second_VideoCard, Second_Memory);c2->work();delete c2;// 第三台电脑cout << "--------第三台电脑--------" << endl;CPU* Third_CPU = new IntelCPU;VideoCard* Third_VideoCard = new LenovoVideoCard;Memory* Third_Memory = new IntelMemory;Computer* c3 = new Computer(Third_CPU, Third_VideoCard, Third_Memory);c3->work();delete c3;}
int main(int argc, char* argv[])
{test();return 0;
}

二、文件操作

程序运行时产生的数据都属于临时数据,程序一旦运行结束都会被释放

通过文件可以将数据持久化

C++中对文件操作需要包含头文件 <fstream>

文件类型分为两种:

1. 文本文件:文件以文本的ASCLL码形式存储在计算机中

2. 二进制文件:文件以文本的二进制形式存储在计算机中,用户一般不能直接读懂他们

操作文件的三大类:

1. ofstream:写操作

2. ifstream:读操作

3. fstream:读写操作

1. 文本文件

1.1 写文件

写文件步骤如下:

1. 包括头文件

        # include <fstream>

2. 创建流对象

        ofstream ofs;

3. 打开文件

        ofs.open("文件路径",打开方式);

4. 写数据

        ofs << "写入的数据";

5. 关闭文件

        ofs.close();

文件打开方式:

打开方式解释
ios::in为读文件而打开文件
ios::out为写文件而打开文件
ios::ate初始位置:文件尾
ios::app追加方式写文件
ios::trunc如果文件存在先删除,再创建
ios::binary二进制方式

注意:文件打开方式可以配合使用,利用 | 操作符

例如:用二进制方式写文件: ios::binary | ios::out

#include <iostream>
#include <fstream>using namespace std;int main(int argc, char* argv[])
{// 1. 包含头文件 fstream// 2. 创建流对象ofstream ofs;// 3. 指定打开方式ofs.open("D:\\test.txt", ios::out);// 4. 写内容ofs << "姓名:张三" << endl;ofs << "年龄:23" << endl;ofs << "性别:男" << endl;ofs << "居住地:地球" << endl;// 5. 关闭文件ofs.close();return 0;
}

总结:

1. 文件操作必须包含头文件 fstream

2. 读文件可以利用ofstream或者fstream类

3. 打开文件时需要指定操作文件的路径,以及打开方式

4. 利用 << 可以向文件中写数据

5. 操作完成后,需要关闭文件

1.2 读文件

读文件与写文件步骤相似,但是读取方式相对比较多

读文件步骤如下:

1. 包含头文件

        # include <fstream>

2. 创建流对象

        ifstream ifs;

3. 打开文件并判断文件是否打开成功

        ifs.open("文件路径",打开方式)

4. 读数据

        四种方式读取

5. 关闭文件

        ifs.close()

#include <iostream>
#include <fstream>
#include <string>using namespace std;void main(int argc, char* argv[])
{// 1. 包含头文件 fstream// 2. 创建流对象ifstream ifs;// 3. 指定打开方式ifs.open("D:\\test.txt", ios::in);// 判断文件是否打开成功if (!ifs.is_open()){cout << "文件打开失败..." << endl;return;}// 4. 读内容// (1).第一种char buffer[1024] = { 0 };while (ifs >> buffer){cout << buffer << endl;}// (2).第二种char buffer[1024] = { 0 };while (ifs.getline(buffer,sizeof(buffer))){cout << buffer << endl;}// (3).第三种string buffer;while (getline(ifs,buffer)){cout << buffer << endl;}// (4).第四种char c;while ((c = ifs.get()) != EOF){cout << c;}// 5. 关闭文件ifs.close();
}

2. 二进制文件

以二进制的方式对文件进行读写操作

打开方式要指定为 ios::binary

2.1 写文件

二进制方式写文件主要利用流对象调用成员函数 write

函数原型:ostream& write(const char * buffer, int len);

参数解释:字符指针buffer指向内存中一段存储空间。len时读写的字节数

#include <iostream>
#include <fstream>using namespace std;class Person
{
public:char m_Name[64];int m_Age;
};void test()
{// 1. 包含头文件 fstream// 2. 创建流对象ofstream ofs;// 3. 指定打开方式ofs.open("D:\\test.txt", ios::out | ios::binary);// 4. 写内容Person p = { "张三",18 };ofs.write((const char*)&p, sizeof(Person));// 5. 关闭文件ofs.close();
}int main(int argc, char* argv[])
{test();return 0;
}

总结:

文件输出流对象可以通过write函数,以二进制方式写数据

2.2 读文件

二进制方式读文件主要利用流对象调用成员函数read

函数原型:istream& read(char * buffer, int len);

参数解释:字符串指针buffer指向内存中一段存储空间。len时读写的字节数

#include <iostream>
#include <fstream>using namespace std;class Person
{
public:char m_Name[64];int m_Age;
};void test()
{// 1. 包含头文件 fstream// 2. 创建流对象ifstream ifs;// 3. 指定打开方式ifs.open("D:\\test.txt", ios::in | ios::binary);// 判断文件是否打开成功if (!ifs.is_open()){cout << "文件打开失败..." << endl;return;}// 4. 写内容Person p;ifs.read((char*)&p, sizeof(Person));cout << "姓名:" << p.m_Name << endl;cout << "年龄:" << p.m_Age << endl;// 5. 关闭文件ifs.close();
}int main(int argc, char* argv[])
{test();return 0;
}

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

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

相关文章

useConsole的封装,vue,react,htmlscript标签,通用

之前用了接近hack的方式实现了console的封装&#xff0c;目标是获取console.log函数的执行&#xff08;调用栈所在位置&#xff09;所在的代码行数。 例如以下代码&#xff0c;执行window.mylog(1)时候&#xff0c;console.log实际是在匿名的箭头函数()>{//这里执行的} con…

【IDEA】Intellij IDEA相关配置

IDEA 全称 IntelliJ IDEA&#xff0c;是java编程语言的集成开发环境。IntelliJ在业界被公认为最好的Java开发工具&#xff0c;尤其在智能代码助手、代码自动提示、重构、JavaEE支持、各类版本工具(git、svn等)、JUnit、CVS整合、代码分析、 创新的GUI设计等方面的功能可以说是超…

SpringCloud源码探析(十二)-基于SpringBoot开发自定义中间件

1.概述 中间件是一种介于操作系统和应用软件之间&#xff0c;为应用软件提供服务功能的软件&#xff0c;按功能划分有消息中间件&#xff08;Kafka、RocketMQ&#xff09;、通信中间件&#xff08;RPC通信中间件&#xff0c;dubbo等&#xff09;&#xff0c;应用服务器等。中间…

Java实现一个在windows环境下的文件搜索引擎

以下是一个简单的Java实现的Windows文件搜索引擎的示例代码&#xff1a; import java.io.File; import java.util.ArrayList; import java.util.List;public class FileSearchEngine {public static void main(String[] args) {String searchDirectory "C:/"; // …

tensorflow入门 自定义模型

前面说了自定义的层&#xff0c;接下来自定义模型&#xff0c;我们以下图为例子 这个模型没啥意义&#xff0c;单纯是为了写代码实现这个模型 首先呢&#xff0c;我们看有几个部分&#xff0c;dense不需要我们实现了&#xff0c;我们就实现Res&#xff0c;为了实现那个*3,我们…

WPF——样式和控件模板、数据绑定与校验转换

样式和控件模板 合并资源字典 Style简单样式的定义和使用 ControlTemplate控件模板的定义和使用 定义 使用 Trigger触发器 数据绑定与校验转换 数据绑定的设置 代码层实现绑定

TransXNet实战:使用 TransXNet实现图像分类任务(二)

文章目录 训练部分导入项目使用的库设置随机因子设置全局参数图像预处理与增强读取数据设置Loss设置模型设置优化器和学习率调整策略设置混合精度&#xff0c;DP多卡&#xff0c;EMA定义训练和验证函数训练函数验证函数调用训练和验证方法 运行以及结果查看测试完整的代码 在上…

监控k8s controller和scheduler,创建serviceMonitor以及Rules

目录 一、修改kube-controller和kube-schduler的yaml文件 二、创建service、endpoint、serviceMonitor 三、Prometheus验证 四、创建PrometheusRule资源 五、Prometheus验证 直接上干货 一、修改kube-controller和kube-schduler的yaml文件 注意&#xff1a;修改时要一个节…

HTML CSS 进度条

1 原生HTML标签 <meter>&#xff1a;显示已知范围的标量值或者分数值<progress>&#xff1a;显示一项任务的完成进度&#xff0c;通常情况下&#xff0c;该元素都显示为一个进度条 1.1 <meter> <html><head><style>meter{width:200px;}…

微软官宣放出一个「小模型」,仅2.7B参数,击败Llama2和Gemini Nano 2

就在前一阵谷歌深夜炸弹直接对标 GPT-4 放出 Gemini 之后&#xff0c;微软这两天也紧锣密鼓进行了一系列动作。尽管时间日趋圣诞假期&#xff0c;但是两家巨头硬碰硬的军备竞赛丝毫没有停止的意思。 就在昨日&#xff0c;微软官宣放出一个“小模型” Phi-2&#xff0c;这个 Ph…

学习k8s

学习k8s 我为什么要用k8s 和其他部署方式的区别是什么? 传统部署方式 java --> package --> 放到服务器上 --> Tomcat 如果是同时进行写操作,会存在并发问题. 用户 --网络带宽–> 服务器 -->服务 同一个服务器上,多个服务: 网络资源的占用 内存的占用 cpu的占…

三、W5100S/W5500+RP2040之MicroPython开发<DNS示例>

文章目录 1. 前言2. 相关网络信息2.1 简介2.2 DNS工作过程2.3 优点2.4 应用 3. WIZnet以太网芯片4. DNS解析示例讲解以及使用4.1 程序流程图4.2 测试准备4.3 连接方式4.4 相关代码4.5 烧录验证 5. 注意事项6. 相关链接 1. 前言 在这个智能硬件和物联网时代&#xff0c;MicroPyt…

【一】FPGA实现SPI协议之SPI协议介绍

【一】FPGA实现SPI协议之SPI协议介绍 一、spi协议解析 spi协议有4根线&#xff0c;主机输出从机输入MOSI、主机输入从机输出MISO、时钟信号SCLK、片选信号SS\CS 。 一般用于主机和从机之间通信。由主机发起读请求和写请求&#xff0c;主机的权限是主动的&#xff0c;从机是被…

C/C++编程中的算法实现技巧与案例分析

C/C编程语言因其高效、灵活和底层的特性&#xff0c;被广大开发者用于实现各种复杂算法。本文将通过10个具体的算法案例&#xff0c;详细探讨C/C在算法实现中的技巧和应用。 一、冒泡排序&#xff08;Bubble Sort&#xff09; 冒泡排序&#xff08;Bubble Sort&#xff09;是一…

【Hadoop精讲】HDFS详解

目录 理论知识点 角色功能 元数据持久化 安全模式 SecondaryNameNode(SNN) 副本放置策略 HDFS写流程 HDFS读流程 HA高可用 CPA原则 Paxos算法 HA解决方案 HDFS-Fedration解决方案&#xff08;联邦机制&#xff09; 理论知识点 角色功能 元数据持久化 另一台机器就…

腾讯云微服务11月产品月报 | TSE 云原生 API 网关支持 WAF 对象接入

2023年 11月动态 TSE 云原生 API 网关 1、支持使用私有 DNS 解析 服务来源支持私有 DNS 解析器&#xff0c;用户可以添加自己的 DNS 解析器地址进行私有域名解析&#xff0c;适用于服务配置了私有域名的用户。 2、支持 WAF 对象接入 云原生 API 网关对接 Web 安全防火墙&…

一种基于外观-运动语义表示一致性的视频异常检测框架 论文阅读

A VIDEO ANOMALY DETECTION FRAMEWORK BASED ON APPEARANCE-MOTION SEMANTICS REPRESENTATION CONSISTENCY 论文阅读 ABSTRACT1. INTRODUCTION2. PROPOSED METHOD3. EXPERIMENTAL RESULTS4. CONCLUSION阅读总结&#xff1a; 论文标题&#xff1a;A VIDEO ANOMALY DETECTION FRA…

锐捷配置完全stub区域

一、实验拓扑 二、实验目的 在运行OSPF协议的网络中&#xff0c;配置STU区域可以减少路由器的路由条目&#xff0c;减小路由器的压力&#xff0c;有效提高路由器的性能。 三、实验配置 第一步&#xff1a;全局配置OSPF R1 ruijie>enable R1#conf terminal R1(config)#hos…

Postman使用总结--生成测试报告

1.执行生成的命令格式 newman run 用例集文件 .json -e 环境文件 .json -d 数据文件 .json/.csv -r htmlextra --reporter- htmlextra-export 测试报告名 .html -e 和 -d 是 非必须的。 如果没有使用 环境&#xff0c;不需要指定 -e 如果没有使用 数据…

数据结构与算法之美学习笔记:37 | 贪心算法:如何用贪心算法实现Huffman压缩编码?

目录 前言如何理解“贪心算法”&#xff1f;贪心算法实战分析解答开篇内容小结 前言 本节课程思维导图&#xff1a; 接下来几节&#xff0c;我会讲几种更加基本的算法。它们分别是贪心算法、分治算法、回溯算法、动态规划。更加确切地说&#xff0c;它们应该是算法思想&#x…