C++要点细细梳理(上)(函数与面向对象)

之前我们讨论了C语言一些基础的细节,下面我们开始讨论C++,,后面我打算接着谈C++++,也就是C#,先在此留个坑。

注意,本文有素材来自中国大学MOOC的C++课程,本文也是该课程的听课笔记【这是链接】

1. 从C到C++

先谈谈C与C++的区别:

  • C语言诞生于1972年,是面向过程的语言,到1980年时,面对日益复杂的问题,C语言不够用了,于是在C语言基础上增加了许多新功能/特性,称这个新版为C++(C加加)
  • 其中C与C++最重要(最本质)的是:
    • C是面向过程的,通过编写函数解决问题
    • C++是面向对象的,同过编写函数和类解决问题

回顾一下面向对象三大特性:继承、多态、封装

  1. 继承:继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。继承是类与类之间的关系,是面向对象最显著的一个特性。通过继承,我们可以实现代码的重用和扩展,减少代码的冗余。继承使用关键字extends来实现。
  2. 多态:多态是指不同的子类在继承父类后分别都重写覆盖了父类的方法,即父类同一个方法,在继承的子类中表现出不同的形式。多态性提供了灵活性和扩展性,使得代码可以处理多种类型的对象,而不需要显式地针对每种类型编写不同的代码。多态性在运行时(而非编译时)能够根据其类型确定调用哪个重载的成员函数。多态是抽象化的一种体现,它允许将子类的对象当作父类的对象使用,提高了程序的可读性和可维护性。
  3. 封装:封装可以将一组相关的变量和函数封装在一个独立的自定义数据类型内,这种独立的数据类型称为类。封装有助于保护数据的完整性和安全性,同时提供了良好的抽象,使得代码更易于理解和使用。封装还可以支持代码的模块化和团队开发,各个模块之间可以独立开发和测试,提高了代码的可维护性和复用性。通过封装,我们可以将数据和它们的操作封装在一个结构里面,使得数据操作更加简单、快捷,同时可以控制访问权限,保证资源不被滥用。
    总的来说,这三大特性共同构成了面向对象编程的基础,它们使得代码更加灵活、易于理解和维护,提高了程序的可重用性和可扩展性。
  • C++是C的一个超集:任何合法的C程序都是合法的C++程序

在这里插入图片描述

1.1 C++输入输出流

  • 流插入运算符:<< ,输出利用iostream库中std命名空间下的cout对象
  • 流提取运算符:>>,输入利用iostream库中std命名空间下的cin对象

1.2 关于命名空间

C++的命名空间(Namespace)是一种将相关的类、函数和变量组织在一起的方式,以避免命名冲突,并提供了一种管理代码的方式。通过使用命名空间,我们可以将不同库或项目中的同名类、函数或变量放在不同的命名空间中,从而避免在引用时产生混淆。

在C++中,可以使用namespace关键字来定义命名空间。例如:

namespace MyNamespace {
    class MyClass {
    public:
        void myFunction() {
            // ...
        }
    };
}

在上面的代码中,我们定义了一个名为MyNamespace的命名空间,并在其中定义了一个名为MyClass的类和一个成员函数myFunction。要使用这个命名空间中的类或函数,我们需要使用MyNamespace::前缀来指定命名空间。例如:

MyNamespace::MyClass obj;
obj.myFunction();

此外,C++还提供了using关键字,它允许我们在特定的作用域内使用命名空间中的名称而不需要前缀。例如:

using namespace MyNamespace;

MyClass obj;
obj.myFunction();

但是需要注意的是,过度使用using namespace可能会导致命名冲突和代码可读性降低,因此在大型项目中应谨慎使用。

总之,C++的命名空间是一种组织和管理代码的有效方式,它可以帮助我们避免命名冲突,提高代码的可读性和可维护性。

命名空间与库(头文件的区别)

  • 本质不同
    • 命名空间是逻辑概念,类似于贴标签:一个命名空间是一种标签纸
    • 库是物理概念,类似于工具箱:一个库含有多个同类工具
  • 目的不同
    • 命名空间为了区别不同工具箱里的同名工具,避免同名歧义
    • 库为了将不同用途的工具分别装在不同的箱子里,实现解耦
      在这里插入图片描述
一句话来说,不同库可能有相同名字的函数,而命名空间就是为了在使用多个库,有多个相同名字函数的时候,你能找到想用的那个函数

例如,你来到一个镇子,这个镇子辖有7个村子,每个村子都有一个叫张三的人,而你想要通过大喇叭找到李村的张三,你有两种做法:

  • 一种是每次喊张三名字的时候带上他的村名,如:李村::张三;
std::cin
  • 另一种做法是喊话前声明,你要找的是李村的人,其他村的别来凑热闹,这样你下面就可以直接喊张三了
using namespace std;
cin

这个例子中,镇子就相当于整个程序,村子相当于引用的数目,喊人前先说是哪个村的,就是命名空间

1.3 字符串类型string

如果要使用printf输出string类型数据,一般要将string转为char *,需要用到c_str();,不然会乱码,如下:

string str="a";
printf("%s",str.c_str());

C++的两个字符串可以使用加号进行拼接,例如

string str1="a";
string str2="b";
string str3=str1+str2;
printf("%s",str3.c_str());//str3="ab"

2. 函数

2.1 默认参数

默认参数需要放在函数声明括号的后面,如

void a(int x,int y=2);

如果放到前面,会造成歧义

2.2 引用传参

左值引用

现有变量,才能引用
给一个已经定义好的、有名字的变量起别名,不存在空的引用
在这里插入图片描述

指针传参与引用传参
void swap_point(int *a,int *b){//指针传参
	int temp =*a;
	*a = *b;
	*b = temp;
}

void swap_quote(int &a,int &b){//引用传参
	int temp =a;
	a = b;
	b = temp;
}
指针传参的作用
  • 指针传参避免了传参时发生的拷贝,实现了在原有数据上的改动
指针传参的缺点
  • 需要使用间接引用符号*,降低代码易读性,编码时候还需考虑运算符优先级
引用传参
  • 传入需要使用变量的别名,同样可以起到修改原有数据的效果

2.3 函数重载overload

C++是强类型语言,同样的操作,如果传入的值和return的值不是一个类型,那么就需要编写不同的函数,为了运行同名但是处理数据类型不同的函数存在,引入函数重载的概念

避免重载产生歧义

在这里插入图片描述
重载与返回值的类型无关,需要满足:

  • 声明时:① 函数名字相同 ② 参数列表不同
  • 调用时:③ 不产生匹配歧义

函数重载(Function Overloading)是C++中的一个特性,它允许在同一个作用域内定义多个同名函数,只要它们的参数列表(即参数的数量、类型或顺序)不同即可。这样,编译器可以根据提供的参数来区分应该调用哪个函数。

对于下面两个函数:

  1. int a(int, int );
  2. int a(int &m, int &n);

它们之所以能够构成函数重载,是因为它们的参数列表不同。尽管两个函数都接受两个int类型的参数,但第二个函数接受的是这两个int的引用(int &),而不是值(int)。

具体来说:

  • 第一个函数接受两个int类型的值作为参数。当调用这个函数时,会创建这两个参数的副本,函数内部的操作不会影响到传入的原始值。
  • 第二个函数接受两个对int的引用作为参数。这意味着函数内部对这两个参数的任何修改都会影响到传入的原始值。

因为C++的类型系统能够区分值类型和引用类型,所以这两个函数具有不同的参数列表,因此可以构成函数重载。

当调用这两个函数时,编译器会根据提供的参数类型(值还是引用)来决定调用哪个函数。例如:

int x = 1, y = 2;
int z = a(x, y);       // 调用第一个函数,因为x和y是值
int &m = x, &n = y;
int p = a(m, n);       // 调用第二个函数,因为m和n是引用

在这个例子中,第一个调用会匹配第一个函数(接受两个值参数的函数),而第二个调用会匹配第二个函数(接受两个引用参数的函数)。

2.4 内联函数inline

inline int getmax(int a,int b,int c){
	return a>b?(a>c?a:c):(b>c?b:c);
}
  • 函数内联发生在编译过程中,用于提升运行时效率
  • 内联函数:指建议编译器编译时将某个函数在调用处直接展开,避免运行时调用开销
  • inline是向编译器建议展开,但是是否真的展开取决于编译器

3. 面向对象Object Orient

3.1 面向对象思想

面向对象思想是一种编程范式,也是软件开发方法。它强调将现实世界的事物抽象为对象,并使用对象及其关系来描述和解决问题。面向对象思想的核心概念包括类、对象、继承、封装和多态。

  • 类与对象:类是对象的模板,它定义了对象的属性和方法。对象是类的实例,具有类所定义的属性和方法。通过类和对象,我们可以将数据和操作数据的方法封装在一起,形成独立的模块。
  • 继承:继承允许我们创建一个新的类(子类),继承自一个已有的类(父类)。子类可以继承父类的属性和方法,并可以添加或覆盖自己的属性和方法。这使得代码可以重用和扩展,提高了开发效率。
  • 封装:封装将数据和方法封装在对象中,使得外部无法直接访问和操作对象内部的数据。这样可以防止数据被随意修改,保护数据的安全性和完整性。同时,封装还使得代码更易于理解和维护。
  • 多态:多态允许我们使用父类类型的引用来引用子类对象,并可以调用被子类覆盖的方法。这使得代码更加灵活和可扩展,能够适应不同的需求和场景。

面向对象思想的优势在于它更符合人类的思维习惯,使得软件设计更加直观和易于理解。同时,面向对象思想也提高了代码的可重用性、可维护性和可扩展性,降低了软件开发的成本。因此,面向对象思想在现代软件开发中得到了广泛应用,并被认为是一种有效的编程范式。

除了软件设计和开发,面向对象思想还扩展到其他领域,如数据库系统、交互式界面、应用结构、应用平台、分布式系统、网络管理结构、CAD技术、人工智能等。在这些领域中,面向对象思想提供了一种对现实世界理解和抽象的方法,使得系统更加灵活、易于理解和维护。

3.2 抽象与UML

3.2.1 抽象:属性+行为

面向对象的抽象是面向对象编程(Object-Oriented Programming, OOP)中的一个核心概念。抽象是指将现实世界中的事物或概念简化为它们的本质特征,同时忽略非本质的细节。在OOP中,抽象的主要目的是实现代码的重用、提高代码的可维护性和可扩展性。

以下是面向对象抽象的一些关键方面:

  1. 抽象类(Abstract Class)
    抽象类是一个不能实例化的类,它通常包含抽象方法(即没有实现的方法)。抽象类用于定义一组相关的对象共有的属性和行为,但它本身并不提供这些行为的具体实现。子类(或称为派生类)必须实现抽象类中的所有抽象方法才能被实例化。
  2. 接口(Interface)
    接口是另一种形式的抽象,它定义了一组方法的签名,但不提供具体的实现。一个类可以实现一个或多个接口,并提供这些接口中定义的方法的具体实现。接口是跨多个不相关类实现共享行为的一种机制。
  3. 封装(Encapsulation)
    封装是与抽象紧密相关的一个概念。它涉及将对象的属性和方法隐藏在其内部,只对外提供有限的访问接口。通过封装,我们可以控制对对象内部状态的访问,从而保护其完整性并减少意外修改的风险。
  4. 继承(Inheritance)
    继承是面向对象编程中实现抽象的一个重要手段。子类可以继承父类的属性和方法,从而重用父类的代码。这有助于减少代码冗余,并促进代码的模块化。

通过抽象,我们可以将复杂的现实世界问题分解为更小的、更易于管理的部分,并用代码来表示这些部分。这使得我们可以构建出更加灵活、可维护和可扩展的软件系统。

3.2.2 UML类图

在这里插入图片描述

在这里插入图片描述

3.3 类、结构体、对象

类与结构体

  • 结构体:主要用于记录数据,很少有行为
  • 类:有属性也有行为

类与对象

  • 类只是一个声明
  • 对象是对类的例化,是真实存在于内存中的

3.4 类的内部结构

3.4.1 类的构造函数与析构函数

  • 构造函数可以有参数也可以没有参数,没有参数时是默认构造函数
  • 析构函数没有参数,用于回收对象所占用的空间
  • 构造函数和析构函数都没有返回值

3.4.2 this指针

在类定义的内部使用,是指向当前对象的指针
在这里插入图片描述
在这里插入图片描述

3.5 面向对象特性

3.5.1 封装:类成员在外部的可见性

  • 如未显式注明,类成员的默认访问控制属性为private
    在这里插入图片描述
getter和setter
  • 通过getter和setter可以实现外部读写私有变量时进行控制
  • getter和setter一般是public
    -
    在这里插入图片描述
    const避免修改,如果修改会报错

3.5.2 继承:代码复用,递进实现更精确的类

继承方式
  • 继承方式:决定父类成员在子类中的访问控制属性
    • 父类的private成员不会被子类继承
    • 公有继承不改变控制属性,保护继承和私有继承指示父类成员在子类中的相应控制属性

在这里插入图片描述

同名成员共存
  • 使用命名空间区分是要用哪个类的成员
虚函数
  • 继承来源于同一对象可能有多重身份,且这些身份有层级递进关系
  • 实践中会有这类情况
    • 父类中的某些行为需要在子类中被更加具体地细化
    • 父类中的某些行为不可确定,必须在子类中实现
  • 于是虚函数的概念产生:
    • 父类的虚函数可以在子类中被重写(override),即重新实现,但参数和返回值必须保持一致,java里面是@override,c++是virtual
  • 含有虚函数的类叫做虚类
    -
    因为仅声明不实现,抽象类和接口不可实例化

3.5.3 多态:父类指针解读不同子类,实现共性操作的代码复用

  • 一个对象就是内存中的一个实体,它只能属于一个确定的类:最精确的子类
  • 它可能在不同处被视为不同身份,但它本质行为方式应与外界如何看待它无关!

问题:如何保证一个对象执行其最本质身份的行为?

  • 利用虚函数重写 + 指针
  • 指针即:指向子类对象的父类指针
多态实现

在这里插入图片描述
在这里插入图片描述

多态的意义
  • 通过“虚函数 +指向子类对象的父类指针”,可以把不同的子类统一视为其共同父类
  • 于是无需针对不同的子类写相同逻辑,统一视作其共同父类,利用指针操作即可
  • 本质是虚函数将能做什么和怎么做分离,父类指定要做什么,子类来实现具体做法
静态联编与动态联编

上述利用虚函数重写+指针实现的多态特指运行时多态,与之相对的是编译时多态
在这里插入图片描述

  • 联编(bind):确定具体要调用多个同名函数中的哪一个
  • 静态联编:在编译时就确定了要调用的是哪个函数(根据多个重载函数的参数列表确定)
  • 动态联编:直到运行时才知道实际调用的是哪个函数(根据指针指向对象的实际身份)

在这里插入图片描述

3.6 对象的拷贝

  • 参数为另一个本类对象的引用的构造函数成为拷贝构造函数,其目的为拷贝另一个对象的内容以初始化本对象,通过引用传参的目的是为了避免不必要的复制。通常还会将这个参数标记为const,如 A(const A& a){// 拷贝行为}

3.6.1 深拷贝与浅拷贝

在这里插入图片描述
在这里插入图片描述

默认拷贝构造函数——浅拷贝
  • 如果没有显式定义拷贝构造函数,则类会默认拥有一个浅拷贝构造函数
  • 因此,如果类内拥有间接资源,记得按需自定义一个深拷贝构造函数

在这里插入图片描述

3.6.2 运算符重载

  • 为自定义的类重载一个运算符函数,其第一个操作数是对象本身,其他操作数是该函数参数
    在这里插入图片描述
重载赋值符号
  • 在定义对象时直接使用赋值号相当于调用拷贝构造函数,如:Aa1=a2;相当于 Aa1(a2);
  • 对已定义对象赋值相当于调用重载的 operator =函数,如无显式定义,则默认进行对象的浅拷贝
  • 在类中有间接资源时,记得按需自定义重载 operator=以实现深拷贝
    在这里插入图片描述
为什么有了指针还要有引用
  • 引用与指针的作用类似:使得函数可以就地修改参数,避免参数的拷贝
  • 且引用的底层实现也利用了指针
  • 因此你应该有此疑问非常久了:为什么有了指针还要有引用
  • 现在学习了运算符重载,你应该可以回答这个问题了
    • 引用使得使用运算符重载时可以不必带着*符号
    • 既清晰美观,又避免了歧义

3.7 类的模块化编程

  • 在C语言中,为了代码的封装,我们会将函数的声明与定义分开
  • 函数声明在 .h 头文件中,定义在 .源代码文件中,将 .编译为二进制文件后同.h 一起交付给使用方
  • 这样使用方编写代码时只看见声明,不会知道具体实现方式
  • C++中编写类也可以使用相同的模块化方式,将声明放在.h 文件中,实现放在.cpp 文件中
    在这里插入图片描述

3.8 类的静态成员

3.8.1 静态static的概念

  • 函数中的static变量存在于全局/静态区,生命周期伴随整个程序,不随着函数结束而死亡
    在这里插入图片描述

3.8.2 类的静态成员

  • 隶属于类,不属于任何一个对象,生命周期贯穿整个程序
  • 类比:静态成员变量是写在设计图纸上的数据,与楼无关
    在这里插入图片描述
  • 类内可直接访问,外部则需要通过 类名:.变量名 访问
  • 静态成员变量必须在类声明外部单独初始化
  • 格式: 数据类型 类名::.变量名 = 初始值,
类的静态成员运用实例:对象计数
  • 类利用其static成员变量来记录它的实例化对象的实时数目
    在这里插入图片描述
  • 静态函数依赖于类,不依赖于任何对象,在静态函数内部也不能使用任何依赖于对象的非静态成员

3.9 构造函数与析构函数调用顺序

3.9.1 构造函数调用顺序::父->子

  • 假设A←B←Q
  • 则实例化一个C类的对象需要调用几个构造函数?仅调用C类的构造函数吗?
  • 显然不够。继承的含义是获取,需要先存在,才能获取
  • 实例化一个C类对象需要依次调用A、B、C的构造函数
    在这里插入图片描述

3.9.2 析构函数调用顺序:子->父

  • 析构函数与构造函数的调用次序刚好相反,先调用子类的析构函数
    在这里插入图片描述

3.10 构造函数的参数列表

在这里插入图片描述

无默认构造函数的父类
  • 试想这种情况:某些成员变量没有无参构造函数
  • 此时无法在构造函数中初始化,因为这样实际上是先默认构造,再赋值
    在这里插入图片描述
构造函数参数列表——让父类提前构造好
  • 构造函数参数列表其实就是一系列构造函数的调用,使它们在本对象构造前构造好
  • 没有默认构造函数的类成员数据或父类必须放在参数列表里构造
    在这里插入图片描述

3.11 拓展知识

3.11.1 多继承与菱形继承

多继承
  • C++允许多继承:一个子类可以继承自多个父类
  • 相当于分别按照指定的继承方式获得这些父类的成员
    在这里插入图片描述
菱形继承
  • 在多继承时有可能出现此情况:多个父类还有它们的共同父类
  • 问题:会出现父类成员多个副本问题
  • 解决方案:虚继承
    在这里插入图片描述

3.11.2 友元函数

  • 好东西当然要和朋友(friend)分享,不要私藏(private)起来或者保护(protected)起来
  • 友元函数虽然需要通过friend关键字在类内进行声明,但并不是类的成员函数!
  • 类的友元函数可以直接访问该类的private和protected成员在这里插入图片描述

3.11.3 虚函数表——运行时多态的C++底层支持

  • 每个对象存有一张虚函数表,记录了其所有虚函数指针
  • 当子类重写父类的虚函数时,用子类重写的版本覆盖父类原有的虚函数指针
  • 因此通过指针调用时会找到最新重写的那个版本
    在这里插入图片描述

3.12 例题

在这里插入图片描述

  • 纯虚函数是一种特殊的虚函数,虚函数可以实现,但是纯虚函数必须是=0的未实现的虚函数
  • 含有一个纯虚函数的类就称为抽象类
  • 接口是由多个纯虚函数组成的

在这里插入图片描述
注意,18题的D项,如果派生类还有一个叫func的函数,这种写法称为函数重写

注意函数重写与函数重载的区别:

函数重写与函数重载在面向对象编程中都是重要的概念,但它们之间存在显著的区别。

首先,函数重写的目的是为了实现多态性。它发生在子类中,子类通过重新定义父类中已有的函数来实现对父类函数的扩展或修改。这种重写要求函数名、参数列表和返回值类型都必须与父类中的函数相同,但函数体可以不同。函数重写发生在运行时,根据对象的实际类型来决定调用哪个函数。

其次,函数重载的主要目的是为了提高代码的可读性和可维护性。它发生在同一个作用域内,允许定义多个具有相同名称但参数列表不同的函数。重载函数的名称必须相同,但参数列表(包括参数的类型、顺序和数量)必须不同。返回类型可以作为重载的区分条件之一,但不是必需的。函数重载发生在编译阶段,根据调用时提供的参数类型和数量来决定调用哪个函数。

此外,从作用域的角度来看,函数重写发生在不同的作用域中,即基类与派生类中。而函数重载则发生在同一个作用域内,子类无法重载父类中的函数。

综上所述,函数重写和函数重载在目的、发生阶段、作用域以及参数要求等方面存在明显的区别。它们各自在面向对象编程中发挥着重要的作用,使得代码更加灵活、可维护和可扩展。

重载overload和重写override的异同

在这里插入图片描述

面向过程与面向对象思想的区别

在这里插入图片描述

从代码编写和底层原理的角度描述动态联编的实现方式

在这里插入图片描述

选择题

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

code reading

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在这里插入图片描述

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

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

相关文章

【HarmonyOS】ArkUI - 动画

利用属性动画、显示动画、组件转场动画实现组件动画效果。 一、属性动画 属性动画是通过设置组件的 animation 属性来给组件添加动画&#xff0c;当组件的 width、height、Opacity、backgroundColor、scale、rotate、translate 等属性变更时&#xff0c;可以实现渐变过渡效果。…

模块化编程:AMD 和 CMD 的魅力

&#x1f90d; 前端开发工程师、技术日更博主、已过CET6 &#x1f368; 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 &#x1f560; 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 &#x1f35a; 蓝桥云课签约作者、上架课程《Vue.js 和 E…

力扣刷题部分笔记

Leetcode 力扣刷题笔记&#xff0c;记录了几个月来的题目记录&#xff0c;将会继续保持刷题~ 2024.01 1768.交替合并字符串 创建字符串不需要声明长度&#xff08;动态分配内存&#xff09;&#xff0c;push_back()可以加入某个字符&#xff0c;append()一般用于添加字符串…

js的qq换肤效果

文章目录 1. 演示效果2. 分析思路3. 代码实现3.1. 方式一3.2. 方式二3.3. 整体代码 1. 演示效果 2. 分析思路 先编写样式&#xff0c;弄好布局和排版。遍历这个集合&#xff0c;对每个图片元素&#xff08;img&#xff09;添加一个点击事件监听器。可以使用 for 或者 forEach …

IT外包服务:企业数据资产化加速利器

随着数字化时代的兴起&#xff0c;数据成为企业最为重要的资源之一。数据驱动创新对于企业的竞争力和可持续发展至关重要。在这一进程中&#xff0c;IT外包服务发挥着关键作用&#xff0c;加速企业数据资产化进程&#xff0c;为企业提供了重要支持。 首先&#xff0c;IT外包服务…

c++11 标准模板(STL)本地化库 - 平面类别 - (std::ctype) 定义字符分类表(四)

本地化库 本地环境设施包含字符分类和字符串校对、数值、货币及日期/时间格式化和分析&#xff0c;以及消息取得的国际化支持。本地环境设置控制流 I/O 、正则表达式库和 C 标准库的其他组件的行为。 平面类别 定义字符分类表 std::ctype template< class CharT > clas…

计算机网络(五) 传输层

传输层 一、传输层概述二、TCP1.报文段格式2.连接管理3.可靠传输4.流量控制5.拥塞控制 三、UDP1.报文段格式2.校验 一、传输层概述 从通信和信息处理的角度看&#xff0c;传输层向它上面的应用层提供通信服务&#xff0c;它属于面向通信部分的最高层&#xff0c;同时也是用户功…

微信小程序纯CSS实现好看的加载动画

进入下面小程序可以体验效果&#xff1a; WXML: <wxs module"img" src"./loading.wxs"></wxs> <view class"loading-container {{show?:loading-container-hide}}"><view class"loading-mask" wx:if"{{ma…

LNMP环境:揭秘负载均衡与高可用性设计

lb1: 192.168.8.5 lb2: 192.168.8.6 web1:192.168.8.7 web2:192.168.8.8 php-fpm: 192.168.8.9 mysql: 192.168.8.10 nfs:192.168.8.11 分别插入镜像 8.5-8.8 分别安装nginx,并设置启动 8.9 安装php 8.10 安装mysql 先配置一台web服务器然后同步 设置网站根目录 cp -…

WebGL BabylonJS GUI 如何创建连接模型的按钮

如图所示&#xff1a; 方法&#xff1a; createGUI(mesh: BABYLON.Mesh, title: string, index: number) {const advancedTexture AdvancedDynamicTexture.CreateFullscreenUI(UI)const rect new Rectangle()rect.width 100pxrect.height 40pxrect.thickness 0advancedT…

在CentOS 8.5.2111下安装vncserver tigervnc-server

# 参考&#xff1a; How to Install TigerVNC Server on CentOS 8 前提&#xff1a; 默认用root操作所有命令 安装桌面GUI dnf groupinstall "Server with GUI" 安装tigervnc-server dnf install tigervnc-server 增加vncuser用户&#xff08;这里默认就是vncuse…

刷题之Leetcode704题(超级详细)

704. 二分查找 力扣题目链接(opens new window)https://leetcode.cn/problems/binary-search/ 给定一个 n 个元素有序的&#xff08;升序&#xff09;整型数组 nums 和一个目标值 target &#xff0c;写一个函数搜索 nums 中的 target&#xff0c;如果目标值存在返回下标&am…

VRRP虚拟路由器冗余协议

vrrp是为了解决单点故障问题 将几台路由器联合成一台虚拟的路由器&#xff0c;保证通信的可靠性 协议小说&#xff1a; 协议不是在固定的哪一个层&#xff0c;是基于哪一层工作&#xff0c;比如说ospf是基于三层工作的 VRRP是基于三层工作的&#xff0c;就在前面会封装一个ip…

GD32F470_ADS1115 超小型 16位 模数转换器 ADC 4通道模块移植

2.9 ADS1115多路模数转换器 ADS1115 器件是兼容 IIC 的 16 位高精度低功耗模数转换器 (ADC)&#xff0c;采用超小型无引线 X2QFN-10 封装和 VSSOP-10 封装。ADS111x 器件采用了低漂移电压基准和振荡器。ADS1114 和 ADS1115 还采用可编程增益放大器(PGA)和数字比较器。这些特性加…

Python云计算技术库之libcloud使用详解

概要 随着云计算技术的发展,越来越多的应用和服务迁移到了云端。然而,不同云服务商的API和接口千差万别,给开发者带来了不小的挑战。Python的libcloud库应运而生,它提供了一个统一的接口,让开发者可以轻松地管理不同云服务商的资源。本文将深入探讨libcloud库的特性、安装…

HCIA-RS基础-STP原理与配置

目录 STP&#xff08;生成树协议&#xff09;原理与配置1. 生成树的产生原因2. 生成树协议的基本原理3. 生成树协议的简单配置4. STP 存在的问题 总结 STP&#xff08;生成树协议&#xff09;原理与配置 1. 生成树的产生原因 在计算机网络中&#xff0c;生成树&#xff08;Sp…

Burp内置浏览器报错提示网页证书无效的解决方式

在Proxy——代理设置中——翻到底&#xff0c;勾选忽略浏览器的Burp错误信息 然后刷新你的网页&#xff0c;就可以按常规操作&#xff0c;点击“继续访问”&#xff0c;打开网页了

Python数据分析和机器学习库之imbalanced-learn使用详解

概要 在实际的数据分析和机器学习任务中,经常会遇到数据不平衡的情况,即不同类别的样本数量差异较大,这会导致模型训练和预测的不准确性。Python的imbalanced-learn库提供了一系列处理不平衡数据的方法和工具,帮助开发者更好地应对这一问题。本文将深入探讨imbalanced-lea…

蓝桥杯算法题:区间移位

题目描述 数轴上有n个闭区间&#xff1a;D1,...,Dn。 其中区间Di用一对整数[ai, bi]来描述&#xff0c;满足ai < bi。 已知这些区间的长度之和至少有10000。 所以&#xff0c;通过适当的移动这些区间&#xff0c;你总可以使得他们的“并”覆盖[0, 10000]——也就是说[0, 100…

zdpcss_transparent_animation_login:使用纯HTML+CSS+JS开发支持设置主题和带动画的科技风登录界面

废话不多说&#xff0c;先上图&#xff0c;有图有真相&#xff1a; 在左下角有一排颜色&#xff0c;点击可以设置主题色&#xff1a; 比如&#xff0c;我这里点击了橙色&#xff0c;登录界面就变成了如下样子&#xff1a; 另外&#xff0c;在输入账号和密码的时候&#x…