当前位置: 首页 > news >正文

多态(C++)

多态

  • 一、初识多态
    • 概念
    • “登场”
      • 1>. 多态的构成条件
      • 2>. 虚函数
      • 3>. 虚函数重写(覆盖)
      • 4>. 虚函数重写的两个例外
        • 1. 协变 一 基类和派生类虚函数返回值类型不同
        • 2. 析构函数重写(基类和派生类析构函数名不同)
    • 小结
  • 二、延伸知识
    • 1>. C++11 override和final
      • 拓展一最终类
    • 2>. 抽象类
      • 概念
      • 接口继承和实现继承
  • 三、原理
    • 1>. 虚函数表(也称虚表)
      • 引入
      • 分析虚表
    • 2>. 多态的原理
    • 3>. 拓展 一 静态绑定和动态绑定
  • 四、单继承和多继承的虚函数表
    • 1>. 单继承中的虚函数表
    • 2>. 多继承中的虚函数表
      • 1. 多继承
      • 2. 菱形继承
      • 3. 菱形虚拟继承

一、初识多态

概念

概念:去完成某个行为,当不同的对象去完成时会产生出不同的状态

eg:
买车票:普通成年人买票时,是全价票;学生买票时,是半价票;

“登场”

1>. 多态的构成条件

  1. 多态是在不同继承关系的类对象,去调用同一函数,产生不同的行为。
  2. 在继承的继承上,需要:
  • 必须通过基类的指针或者引用调用虚函数
  • 被调用的函数必须是虚函数,且派生类必须对基类的虚函数进行重写 (覆盖)

eg: “见见猪跑”
多态

2>. 虚函数

虚函数:被virtual修饰的类成员函数

虚函数

3>. 虚函数重写(覆盖)

虚函数重写(覆盖):派生类中有一个跟基类完全相同的虚函数(即派生类虚函数与基类虚函数的返回值类型,函数名,参数类型完全相同)。称子类的虚函数重写了父类的虚函数

注意: 重写基类虚函数时,派生类的虚函数可以不加virtual关键字。
eg:
virtual

4>. 虚函数重写的两个例外

虚函数重写的要求是派生类虚函数与基类虚函数的返回值类型,函数名,参数类型完全相同(三同)。例外的原因就是不满足三同

1. 协变 一 基类和派生类虚函数返回值类型不同

协变:派生类重写基类虚函数时,与基类虚函数返回值类型不同。
满足协变的条件:返回值类型可以不同,但是返回值必须是父子关系的指针或引用

test code:

class A
{};
class B : public A
{};class Person
{
public:virtual A* f(){return new A;}
};class Student : public Person
{
public://注意在重写的地方,返回值类型虽然可以不同,但是必须是父子关系,而且同指针或同引用。不能出现基类虚函数返回值类型是父类引用,而派生类重写的虚函数返回类型是派生类的指针virtual B* f(){return new B;}
};

2. 析构函数重写(基类和派生类析构函数名不同)

基类的析构函数为虚函数,则派生类析构函数只要定义,无论是否加virtual关键字,都构成重写。虽然表象函数名不同,但是编译器对析构函数的名称做了特殊处理,编译后析构函数的名称统一处理成destructor

test code:

class Person
{
public:virtual ~Person(){cout << "~Person()" << endl;}
};class Student : public Person
{
public:virtual ~Student(){cout << "~Student()" << endl;}
};//只有派生类Student的析构函数重写了Person的析构函数,
//这时delete调用析构时,才能构成多态,保证正确调用析构函数
int main()
{Person* p1 = new Person;Person* p2 = new Student;delete p1;delete p2;return 0;
}//output:
//~Person()
//~Student()
//~Person()

小结

重载、覆盖(重写)、隐藏(重定义)的对比:
重载、覆盖(重写)、隐藏(重定义)的对比

二、延伸知识

1>. C++11 override和final

  1. override:检查派生类虚函数是否重写了基类某个虚函数,如果没有重写报错

test code:

class Car
{
public:virtual void Drive() {}
};class Benz : public Car
{
public:virtual void Drive() override   //ok  完成了重写{cout << "Benz-舒适" << endl;}
};
  1. final:修饰虚函数,表示该虚函数不能再被重写

test code:

class Car
{
public:virtual void Drive() final{}
};class Benz : public Car
{
public:virtual void Drive()  //error  原因:final禁止了重写{cout << "Benz-舒适" << endl;}
};

拓展一最终类

当我们想设计不想被继承的类时,有两种方法

方法1 一一 对应C++98

eg1: 隐藏构造函数,当想要创建A对象时,定义一个静态的成员函数

class A
{
public:static A CreateObj(){return A();}
private:A(){}
};class B : public A
{};int main()
{//B bb;     //errA::CreateObj();return 0;
}

eg2:隐藏析构函数,当想要创建A对象new一个,释放时定义一个静态的destructor,即可

class A
{
public:
private:~A(){}
};
class B : public A
{};int main()
{//B bb;   //errA* p = new A;return 0;
}

方法2 一一 对应C++11
eg:被final修饰的类,被称为最终类,不能被继承

class A final
{
public:
private:
};
class B : public A
{};

2>. 抽象类

概念

  1. 纯虚函数:虚函数的后面写上 = 0
  2. 抽象类(接口类):包含纯虚函数的类。
    抽象类不能实例化出对象,派生类继承后也不能,只有重写纯虚函数,派生类才可以实例化对象。规范了派生类必须重写。

test code:

class Car
{
public:virtual void Drive() = 0;
};class Benz : public Car
{
public:virtual void Drive(){cout << "Benz-舒适" << endl;}
};class BMW : public Car
{
public:virtual void Drive(){cout << "BMW-好操控" << endl;}
};int main()
{Car* pBenz = new Benz;pBenz->Drive();Car* pBMW = new BMW;pBMW->Drive();return 0;
}

接口继承和实现继承

  1. 实现继承:普通函数继承。派生类继承基类函数,可以使用,继承的是函数实现。
  2. 接口继承:虚函数的继承。派生类继承的是虚函数的接口,目的是为了重写,达成多态,继承的是接口。
    注意:不实现多态就不要把函数定义成虚函数

三、原理

基于vs2019进行模型分析

1>. 虚函数表(也称虚表)

引入

test code:

//计算Base对象的大小
class Base
{
public:virtual void Func(){cout << "Func()" << endl;}private:int _b = 1;
};int main()
{Base b;cout << sizeof(b) << endl;return 0;
}
//output: 8

代码分析:
模型分析

分析虚表

test code:

class Base
{
public:virtual void Func1(){cout << "Base::Func1()" << endl;}virtual void Func2(){cout << "Base::Func2()" << endl;}void Func3(){cout << "Base::Func3()" << endl;}private:int _b = 1;
};class Derive : public Base
{
public:virtual void Func1(){cout << "Derive::Func1()" << endl;}
private:int _d = 2;
};int main()
{Base b;Derive d;return 0;
}

通过上面的测试代码,发现一下六点:

虚表

2>. 多态的原理

上面分析了很久的虚表,以对虚表的介绍为基础,来分析多态的原理。

test code:

class Person
{
public:virtual void BuyTicket(){cout << "买票-全价" << endl;}
};
class Student : public Person
{
public:virtual void BuyTicket(){cout << "买票-半价" << endl;}
};void Func(Person* p)
{p->BuyTicket();
}int main()
{Person ps;Func(&ps);ps.BuyTicket();Student st;Func(&st);return 0;
}

达到多态,有两个条件:一是虚函数覆盖,一个是对象的指针或引用调用虚函数。
通过下面汇编代码的分析,看出满足多态以后的函数调用,不是在编译时确定的,是运行起来以后到对象中去找的。不满足多态的函数调用是编译时确认好的。

函数覆盖

对象的指针或引用

3>. 拓展 一 静态绑定和动态绑定

  1. 静态绑定(前期绑定):在程序编译期间确定了程序的行为,也称静态多态。 eg:函数重载
  2. 动态绑定(后期绑定):是在程序运行期间,根据具体拿到的类型确定程序的具体行为,调用具体的函数,也称动态多态

上一个汇编代码的例子,就很好的解释了静态绑定和动态绑定

四、单继承和多继承的虚函数表

1>. 单继承中的虚函数表

test code:

class Base
{
public:virtual void func1(){cout << "Base::func1()" << endl;}virtual void func2(){cout << "Base::func2()" << endl;}
private:int _b;
};class Derive : public Base
{
public:virtual void func1(){cout << "Derive::func1()" << endl;}virtual void func3(){cout << "Derive::func3()" << endl;}virtual void func4(){cout << "Derive::func4()" << endl;}
private:int _d;
};int main()
{Base b;Derive d;return 0;
}

观察下图中监视窗口,发现派生类的虚函数func3和func4看不见。 原因:编译器的监视窗口隐藏了这个两个函数。

查看虚表

在分析虚表这一小节内容时,在第四小点说到,虚表本质是一个存虚函数指针的指针数组,一般情况这个数组最后放一个nullptr,通过监视窗口查看不了派生类对象d的虚表,下面我们借用nullptr的帮助,使用代码打印出虚表中的函数

PrintVTable_code:打印虚表的代码

注意:这个打印虚表的代码经常崩溃,编译器对虚表的处理不干净,虚表最后没有放nullptr的指针,导致越界。我们只需要清理解决方案,重新编译即可。

typedef void(*VFPtr) ();  //函数指针
void PrintVTable(VFPtr VTable[])
{//依次取虚表中的虚函数指针打印并调用。cout << "虚表地址>" << VTable << endl;for (size_t i = 0; VTable[i] != nullptr; i++){printf("第%d个虚函数地址:0X%p,->", i, VTable[i]);VFPtr f = VTable[i];f();    //调用方便看存的是那个函数}cout << endl;
}

注意:传参调用PrintVTable的思路

int main()
{Base b;Derive d;//思路:取b、d对象的头4个字节,就是虚表的指针。//以b对象讲解//1.先取b的地址,强转成int*的指针//2.再解引用取值,就取到b对象头4个字节的值,也就是指向虚表的指针//3.再强转成VFPtr*,因为虚表就是一个存VFPtr类型(虚函数指针类型)的数组//4.虚表指针传递给PrintVTable进行打印虚表VFPtr* vTable_b = (VFPtr*)(*(int*)&b);PrintVTable(vTable_b);VFPtr* vTable_d = (VFPtr*)(*(int*)&d);PrintVTable(vTable_d);return 0;
}

上面代码打印出虚表中虚函数的结果分析:
代码打印出虚表中虚函数的结果分析

2>. 多继承中的虚函数表

1. 多继承

test code:

class Base1
{
public:virtual void func1(){cout << "Base1::func1()" << endl;}virtual void func2(){cout << "Base1::func2()" << endl;}
private:int _b1 = 1;
};class Base2
{
public:virtual void func1(){cout << "Base2::func1()" << endl;}virtual void func2(){cout << "Base2::func2()" << endl;}
private:int _b2 = 1;
};class Derive : public Base1, public Base2
{
public:virtual void func1(){cout << "Derive::func1()" << endl;}virtual void func3(){cout << "Derive::func3()" << endl;}
private:int _d = 2;
};typedef void(*VFPtr) ();  //函数指针
void PrintVTable(VFPtr vTable[])
{//依次取虚表中的虚函数指针打印并调用。cout << "虚表地址>" << vTable << endl;for (size_t i = 0; vTable[i] != nullptr; i++){printf("第%d个虚函数地址:0X%p,->", i, vTable[i]);VFPtr f = vTable[i];f();    //调用方便看存的是那个函数}cout << endl;
}int main()
{Derive d;VFPtr* vTable_b1 = (VFPtr*)(*(int*)&d);PrintVTable(vTable_b1);//(char*)&d  这里一定要注意强转,否则+1,就是加一个Derive的大小VFPtr* vTable_b2 = (VFPtr*)(*(int*)((char*)&d + sizeof(Base1)));PrintVTable(vTable_b2);return 0;
}

多继承测试代码展开分析:
多继承测试代码分析

2. 菱形继承

test code:

#include<iostream>
using namespace std;
class A
{
public:virtual void fun1(){cout << "A::fun1()" << endl;}int _a = 0;
};class B : public A
{
public:virtual void fun1(){cout << "B::fun1()" << endl;}virtual void fun2(){cout << "B::fun2()" << endl;}int _b = 0;
};class C : public A
{
public:virtual void  fun1(){cout << "C::fun1()" << endl;}virtual void fun2(){cout << "C::fun2()" << endl;}int _c = 0;
};
class D : public B, public C
{
public:virtual void  fun2(){cout << "D::fun2()" << endl;}virtual void fun3(){cout << "D::fun3()" << endl;}
};typedef void(*VFPtr) ();  //函数指针
void PrintVTable(VFPtr vTable[])
{//依次取虚表中的虚函数指针打印并调用。cout << "虚表地址>" << vTable << endl;for (size_t i = 0; vTable[i] != nullptr; i++){printf("第%d个虚函数地址:0X%p,->", i, vTable[i]);VFPtr f = vTable[i];f();    //调用方便看存的是那个函数}cout << endl;
}int main()
{D d;VFPtr* vTable_d = (VFPtr*)(*(int*)&d);PrintVTable(vTable_d);C* ptr1 = &d;VFPtr* vTable_c = (VFPtr*)(*(int*)ptr1);PrintVTable(vTable_c);return 0;
}

菱形继承测试代码展开分析:(菱形继承和多继承没有什么大的区别)
菱形继承测试代码展开分析

3. 菱形虚拟继承

  1. 只有A类有虚函数

test code:

class A
{
public:virtual void fun1(){cout << "A::fun1()" << endl;}
public:int _a = 0;
};class B : virtual public A
{
public:int _b = 0;
};class C : virtual public A
{
public:int _c = 0;
};
class D : public B, public C
{
public:int _d;
};int main()
{D d;d.B::_a = 1;d.C::_a = 2;d._b = 3;d._c = 4;d._d = 5;return 0;
}

代码内存分析:
代码内存分析

  1. B和C完成对A的虚函数重写

test code:

class A
{
public:virtual void fun1(){cout << "A::fun1()" << endl;}
public:int _a = 0;
};class B : virtual public A
{
public:virtual void fun1(){cout << "B::fun1()" << endl;}
public:int _b = 0;
};class C : virtual public A
{
public:virtual void fun1(){cout << "C::fun1()" << endl;}
public:int _c = 0;
};
class D : public B, public C
{
public:int _d;
};int main()
{D d;d.B::_a = 1;d.C::_a = 2;d._b = 3;d._c = 4;d._d = 5;return 0;
}

运行结果:
编译报错

原因:因为整个对象只有A一张虚表是共享的,B要重写,C也要重写。不明确到底重写谁的。
解决办法:让D重写即可。当然B和C的重写并不是没有意义,如果定义B和C类型的对象,单独使用还是有意义的。

  1. 只有A类有虚函数 + B和C有单独的虚函数

test code:

class A
{
public:virtual void func1(){cout << "A::func1" << endl;}
public:int _a;
};class B : virtual public A
{
public:virtual void func1(){cout << "B::func1" << endl;}virtual void func2(){cout << "B::func2" << endl;}
public:int _b;
};class C : virtual public A
{
public:virtual void func1(){cout << "C::func1" << endl;}virtual void func2(){cout << "C::func2" << endl;}
public:int _c;
};class D : public B, public C
{
public:virtual void func1(){cout << "D::func1" << endl;}public:int _d;
};int main()
{D d;d.B::_a = 1;d.C::_a = 2;d._b = 3;d._c = 4;d._d = 5;return 0;
}

代码内存分析:
代码内存分析

  1. 如果在第三点的基础上,D类也有自己的虚函数,那么将放哪里?

test code:

class A
{
public:virtual void func1(){cout << "A::func1" << endl;}
public:int _a;
};class B : virtual public A
{
public:virtual void func1(){cout << "B::func1" << endl;}virtual void func2(){cout << "B::func2" << endl;}
public:int _b;
};class C : virtual public A
{
public:virtual void func1(){cout << "C::func1" << endl;}virtual void func2(){cout << "C::func2" << endl;}
public:int _c;
};class D : public B, public C
{
public:virtual void func1(){cout << "D::func1" << endl;}virtual void func3(){cout << "D::func3" << endl;}public:int _d;
};typedef void(*VFPtr) ();  //函数指针
void PrintVTable(VFPtr vTable[])
{//依次取虚表中的虚函数指针打印并调用。cout << "虚表地址>" << vTable << endl;for (size_t i = 0; vTable[i] != nullptr; i++){printf("第%d个虚函数地址:0X%p,->", i, vTable[i]);VFPtr f = vTable[i];f();    //调用方便看存的是那个函数}cout << endl;
}int main()
{D d;VFPtr* vTable_d = (VFPtr*)(*(int*)&d);    //B的虚表PrintVTable(vTable_d);C* ptr1 = &d;VFPtr* vTable_c = (VFPtr*)(*(int*)ptr1);  //C的虚表PrintVTable(vTable_c);A* ptr2 = &d;VFPtr* vTable_a = (VFPtr*)(*(int*)ptr2);  //A的虚表PrintVTable(vTable_a);return 0;
}

运行结果:由结果得到D类自己的虚函数放在第一张虚表中
代码运行结果

相关文章:

多态(C++)

多态 一、初识多态概念“登场”1>. 多态的构成条件2>. 虚函数3>. 虚函数重写&#xff08;覆盖&#xff09;4>. 虚函数重写的两个例外1. 协变 一 基类和派生类虚函数返回值类型不同2. 析构函数重写&#xff08;基类和派生类析构函数名不同&#xff09; 小结 二、延伸…...

算法leetcode|73. 矩阵置零(rust重拳出击)

文章目录 73. 矩阵置零&#xff1a;样例 1&#xff1a;样例 2&#xff1a;提示&#xff1a;进阶&#xff1a; 分析&#xff1a;题解&#xff1a;rust&#xff1a;go&#xff1a;c&#xff1a;python&#xff1a;java&#xff1a; 73. 矩阵置零&#xff1a; 给定一个 m x n 的矩…...

axios 二次封装

axios 二次封装 基本上每一个项目开发&#xff0c;都必须要二次封装 axios。主要是为了减少重复性工作&#xff0c;不可能每一次发起新请求时&#xff0c;都要重新配置请求域名、请求头 Content-Type、Token 等信息。所以需要把公用的部分都封装成一个函数&#xff0c;每次调用…...

Rust安全之数值

文章目录 数值溢出 数值溢出 编译通过,运行失败 cargo run 1 fn main() {let mut arg std::env::args().skip(1).map(|x| x.parse::<i32>().unwrap()).next().unwrap();let m_i i32::MAX - 1;let a m_i arg;println!("{:?}", a); }thread main panicked…...

4种方法实现html 页面内锚点定位及跳转

使用scrollIntoView进行锚点定位效果 不知道你有没有遇到这样的需求&#xff1a;锚点定位&#xff1f;进入页面某个元素需要出现在可视区&#xff1f;…这一类的需求归根结底就是处理元素与可视区域的关系。我接触了很多前端小伙伴&#xff0c;实现的方式有各种各样的&#xff…...

gitlab配置备忘

版本 gitlab 14.6.2 gitlab备份上传到阿里云oss ### Backup Settings ###! Docs: https://docs.gitlab.com/omnibus/settings/backups.html# gitlab_rails[manage_backup_path] true # gitlab_rails[backup_path] "/var/opt/gitlab/backups"###! Docs: https://…...

基于Centos搭建k8s仓库

系统环境&#xff1a; Red Hat Enterprise Linux 9.1 (Plow) Kernel: Linux 5.14.0-162.6.1.el9_1.x86_64 主机名地址master192.168.19.128node01192.168.19.129node02192.168.19.130 目录 1、关闭防火墙&#xff0c;关闭SElinxu &#xff0c;开启时间同步服务 2、关…...

浅谈泛在电力物联网发展形态与技术挑战

安科瑞 华楠 摘 要&#xff1a;泛在电力物联网是当前智能电网发展的一个方向。首先&#xff0c;总结了泛在电力物联网的主要作用和价值体现&#xff1b;其次&#xff0c;从智能电网各个环节概述了物联网技术在电力领域的已有研究和应用基础&#xff1b;进而&#xff0c;构思并…...

git reset --soft 用法

git reset --soft 是 Git 命令中的一个选项&#xff0c;它用于取消之前的提交&#xff0c;并将取消的更改保留在暂存区。这允许您重新组织提交历史或将更改合并到一个新的提交中&#xff0c;而不影响暂存区和工作目录中的更改。 这个命令的语法是&#xff1a; git reset --so…...

哪些测试仪器可以用于检测静电中和设备的性能

静电设备性能测试通常需要使用一些专门的仪器来进行。以下是一些常见的静电设备性能测试仪器&#xff1a; 1. 静电电压测试仪&#xff1a;用于测量物体表面的静电电压。它通常可以测量正负电压&#xff0c;并具有高精度和快速响应的特点。 2. 静电电荷仪&#xff1a;用于测量物…...

浅析 GlusterFS 与 JuiceFS 的架构异同

在进行分布式文件存储解决方案的选型时&#xff0c;GlusterFS 无疑是一个不可忽视的考虑对象。作为一款开源的软件定义分布式存储解决方案&#xff0c;GlusterFS 能够在单个集群中支持高达 PiB 级别的数据存储。自从首次发布以来&#xff0c;已经有超过十年的发展历程。目前&am…...

ARM开发,stm32mp157a-A7核PWM实验(驱动蜂鸣器,风扇,马达工作)

1.分析框图&#xff1b; 2.比较捕获寄存器&#xff08;产生PWM方波&#xff09;&#xff1b; 工作原理&#xff1a; 1、系统提供一个时钟源209MHZ&#xff0c;需要通过分频器进行分频&#xff0c;设置分频器值为209分频&#xff1b; 2、当定时器启动之后&#xff0c;自动重载…...

群狼调研(长沙眼镜店神秘顾客)|消费者需求研究方案

本文由群狼调研(长沙品牌调研)出品&#xff0c;欢迎转载&#xff0c;请注明出处。消费者需求研究方案是在开展研究之前制定的计划&#xff0c;用于指导研究的设计、实施和分析。以下是一个可能的消费者需求研究方案的大致框架&#xff1a; 1. 研究目标和问题&#xff1a; • …...

电脑入门:宽带路由器常见故障排除技巧

宽带路由器在企业网络中的应用是相当广泛的,在运行的过程中出现故障是在所难免的,虽然故障现象多种多样,引起故障发生的原因也不尽相同,但从大体上可以把这些故障分为硬件故障和软件故障,具体来说就是一些网络连接性问题、配置文件选项问题以及网络协议问题等。 由于路由器…...

基于云原生网关的流量防护实践

作者&#xff1a;涂鸦 背景 在分布式系统架构中&#xff0c;每个请求都会经过很多层处理&#xff0c;比如从入口网关再到 Web Server 再到服务之间的调用&#xff0c;再到服务访问缓存或 DB 等存储。在下图流量防护体系中&#xff0c;我们通常遵循流量漏斗原则进行流量防护。…...

开源与云计算:新的合作模式

&#x1f337;&#x1f341; 博主猫头虎 带您 Go to New World.✨&#x1f341; &#x1f984; 博客首页——猫头虎的博客&#x1f390; &#x1f433;《面试题大全专栏》 文章图文并茂&#x1f995;生动形象&#x1f996;简单易学&#xff01;欢迎大家来踩踩~&#x1f33a; &a…...

前端需要理解的跨平台知识

混合开发是指使用多种开发模开发App的一种开发模式&#xff0c;涉及到两大类技术&#xff1a;原生 Native、Web H5。原生 Native 主要指 iOS&#xff08;Objective C&#xff09;、Android&#xff08;Java&#xff09;&#xff0c;原生开发效率较低&#xff0c;开发完成需要重…...

《基于 Vue 组件库 的 Webpack5 配置》3.将 CSS 提取到单独的文件

使用 webpack 插件 mini-css-extract-plugin 需要额外安装 npm i mini-css-extract-pluginlatest -D&#xff1b; 同时打包 js 和 css 文件时&#xff0c;可参考 entry 高级用法&#xff1b; package.json 的配置如下 const { VueLoaderPlugin } require(vue-loader); // 可…...

2023CCF图形学启明星计划夏令营感想记录

这篇就是纯日记了&#xff0c;想记录一下参加这个夏令营的感想&#xff0c;中间的一些过程&#xff0c;毕竟这对我来说算是一段难忘的经历。 一、了解到的渠道 我个人是比较喜欢图形渲染的&#xff0c;之前也学过GAMES的课程&#xff0c;然后偶然的一天&#xff0c;GAMES101里…...

如何解决“缺失msvcp110.dll”错误,msvcp110.dll丢失要怎样才能修复

今天&#xff0c;我将为大家分享关于电脑提示msvcp110.dll丢失的3种修复方法。希望这些方法能帮助到正在遇到这个问题的朋友们。 首先&#xff0c;我们来了解一下msvcp110.dll文件的作用。msvcp110.dll是Microsoft Visual C 2010 Redistributable Package的一部分&#xff0c;…...

激活函数总结(二十):激活函数补充(SQNL、PLU)

激活函数总结&#xff08;二十&#xff09;&#xff1a;激活函数补充 1 引言2 激活函数2.1 Square nonlinearity (SQNL)激活函数2.2 Piecewise Linear Unit (PLU)激活函数 3. 总结 1 引言 在前面的文章中已经介绍了介绍了一系列激活函数 (Sigmoid、Tanh、ReLU、Leaky ReLU、PR…...

Docker【部署 04】Docker Compose下载安装及实例Milvus Docker compose(CPU)使用说明分享

Docker Compose 下载安装使用说明 1.Compose说明1.1 Overview of installing Docker Compose1.2 Installation scenarios1.2.1 Scenario one: Install Docker Desktop1.2.2 Scenario two: Install the Compose plugin1.2.3 Scenario three: Install the Compose standalone 2.C…...

23种设计模式-7种结构模式

结构型模式简述 把类或对象结合在一起形成一个更大的结构。 装饰器模式&#xff1a;动态的给对象添加新的功能。 代理模式&#xff1a;为其它对象提供一个代理以便控制这个对象的访问。 桥接模式&#xff1a;将抽象部分和它的实现部分分离&#xff0c;使它们都可以独立的变…...

大数据Flink(六十七):SQL Table 简介及运行环境

文章目录 SQL & Table 简介及运行环境 一、​​​​​​​​​​​​​​简介 二、案例...

WPF使用依赖注入

现在依赖注入在.Net里面已经普及&#xff0c;自己常写一些简单的demo倒是无所谓&#xff0c;但偶尔写一点正式的工程&#xff0c;也免不了要使用一下&#xff0c;于是总结了一下在WPF里面使用依赖注入。 在写简单Demo时候&#xff0c;通常是在MainWindow的构造函数里面直接做初…...

玩转科技|了解AI平台桌面客户端—ChatBox

目录 前言 特性 ​编辑 为什么需要 ChatBox&#xff1f; ChatGPT Plus 平替&#xff1f; 下载 支持系统 功能图 使用教程 ​感受 展示 前言 今天小编又来了&#xff0c;推荐给大家一款开源的OpenAI API桌面客户端ChatBox&#xff0c;它支持 Windows、Mac 和 Linux。…...

visual studio 2022.NET Core 3.1 未显示在目标框架下拉列表中

问题描述 在Visual Studio 2022我已经安装了 .NET core 3.1 并验证可以运行 .NET core 3.1 应用程序&#xff0c;但当创建一个新项目时&#xff0c;目标框架的下拉列表只允许 .NET 6.0和7.0。而我在之前用的 Visual Studio 2019&#xff0c;可以正确地添加 .NET 核心项目。 …...

人工智能项目集合推荐(数据集 模型训练 C++和Android部署)

人工智能项目集合推荐(数据集 模型训练 C和Android部署) 目录 人工智能项目集合推荐(数据集 模型训练 C和Android部署) 1.三维重建项目集合 ★双目三维重建 ★结构光三维重建 2.AI CV项目集合 ★人脸检测和人体检测 ★人体姿态估计(人体关键点检测) ★头部朝向估计 …...

C# 服务HTTPS 对 请求被中止: 未能创建 SSL/TLS 安全通道报错

1.如果windows支持HTTPS的TLS协议&#xff0c;则可以直接跳过 &#xff08;Tls12&#xff09; [WebMethod(Description "获取HttpsPost加密服务.")] public string HTTPSPOST(String input,String sUrl) { Log.Add("ReceiveNotice", &qu…...

二级MySQL(七)——表格数据修改

1、修改表格中部分数据 将表格某一行的数据修改&#xff0c;这里用的UPDATE语句&#xff1a; UPDATE tb_student SET studentName 黄涛,native湖北,nation汉 WHERE studentNo 2014210103; 结果&#xff1a; 2、修改表格某一列全部数据 比如性别全部设置为‘女’ UPDATE…...

【日常积累】Linux下sftp搭建

概述 SFTP是Secure File Transfer Protocol的缩写&#xff0c;是安全文件传送协议。可以为传输文件提供一种安全的加密方法。跟ftp几乎语法功能一样。 SFTP是SSH的一部分&#xff0c;是一种传输档案至Blogger伺服器的安全方式。它本身没有单独的守护进程&#xff0c;必须使用s…...

【深入浅出C#】章节 9: C#高级主题:多线程编程和并发处理

多线程编程和并发处理的重要性和背景 在计算机科学领域&#xff0c;多线程编程和并发处理是一种关键技术&#xff0c;旨在充分利用现代计算机系统中的多核处理器和多任务能力。随着计算机硬件的发展&#xff0c;单一的中央处理单元&#xff08;CPU&#xff09;已经不再是主流&a…...

Windows Server服务器安全加固基线配置

一、账户管理、认证授权 一、账户 1、管理缺省账户 安全基线项说明&#xff1a;对于管理员账号&#xff0c;要求更改缺省账户名称&#xff1b;禁用Guest(来宾)账户。 操作步骤&#xff1a;进入控制面板-->管理工具-->计算机管理&#xff0c;在系统工具-->本地用户和组…...

基于NXP i.MX 6ULL核心板的物联网模块开发案例(4)

目录 5 4G模块测试 5.1 网络功能测试 5.2 短信功能测试 5.3 通话功能测试 5.4 GPS定位功能测试 5.5 程序编译 前言 本文主要介绍基于创龙科技TLIMX6U-EVM评估板的物联网模块开发案例,适用开发环境: Windows开发环境:Windows 7 64bit、Windows 10 64bit 虚拟机:VMware15.…...

英语——强调

强调句是英语中常用的一个重点句型,其基本结构是:It+be+被强调部分+that+句子其余部分。 第一节 强调句的基本用法 一、被强调的句子成分 在强调句型中,能够被强调的句子成分通常为主语、宾语、状语等,不能用来强调谓语动词、表语、补语、让步状语、条件状语等。当被强调…...

全流程R语言Meta分析核心技术教程

详情点击链接&#xff1a;全流程R语言Meta分析核心技术教程 一&#xff0c;Meta分析的选题与检索 1、Meta分析的选题与文献检索 1)什么是Meta分析&#xff1f; 2)Meta分析的选题策略 3)精确检索策略&#xff0c;如何检索全、检索准 4)文献的管理与清洗&#xff0c;如何制定文…...

【C++精华铺】9.STL string

目录 1. string类的优势 2. string类的常用接口 2.1 常用构造 1. 空串构造&#xff1a;string(); 2. C串构造&#xff1a;string(const char* s); 3. 拷贝构造&#xff1a;string(const string& str); 4. 字符填充构造&#xff1a;string(size_t n, char c); 5. 迭代…...

【PACS】医学影像管理系统源码带三维重建后处理技术

PACS系统&#xff0c;意为影像归档和通信系统。它是应用在医院影像科室的系统&#xff0c;主要的任务就是把日常产生的各种医学影像&#xff08;包括核磁&#xff0c;CT&#xff0c;超声&#xff0c;各种X光机&#xff0c;各种红外仪、显微仪等设备产生的图像&#xff09;通过各…...

从0开始学go 第一天

今天是开始学go的第x天&#xff0c;前些日子看了看语言&#xff0c;今天找一个web开发来跟着学&#xff0c;记录一下遇到的问题&#xff0c;方便以后复习查阅。 视频看的是https://www.bilibili.com/video/BV1gJ411p7xC?p3&vd_sourceab5bdbd04f4142027c66d604d5285204 视…...

Spring Cloud Nacos详解

目录 1、Spring Cloud Nacos详细介绍2、Spring Cloud Nacos具体案列 Spring Cloud Nacos 是一个由阿里巴巴集团开发的开源分布式系统服务发现、配置管理和服务管理的平台。Nacos 支持多种服务发现方式&#xff0c;包括 DNS 方式、HTTP 和 RPC 方式&#xff0c;同时提供了灵活的…...

2023谷歌开发者大会直播大纲「初稿」

听人劝、吃饱饭,奉劝各位小伙伴,不要订阅该文所属专栏。 作者:不渴望力量的哈士奇(哈哥),十余年工作经验, 跨域学习者,从事过全栈研发、产品经理等工作,现任研发部门 CTO 。荣誉:2022年度博客之星Top4、博客专家认证、全栈领域优质创作者、新星计划导师,“星荐官共赢计…...

react import 引用失效 node_modules/@types/react/index.d.ts not a module.ts

问题描述 react ts的项目&#xff0c;正常使用vs code打开&#xff0c; 先运行 npm install 安装依赖过后 结果所有的react引用依旧标红&#xff0c;如下图所示&#xff1a; 点击红线 show problem(查看问题)&#xff0c;提示node_modules/types/react/index.d.ts not a mod…...

Unity中的Unistorm3.0天气系统笔记

Unistorm是Unity中的一个天气系统&#xff0c;它功能强大&#xff0c;效果优美。本文所述UniStorm为3.0版本&#xff0c;仅用于学习之用。 一、如何设置【白天】、【黑夜】和【天气类型】&#xff1f; 在Running模式下&#xff0c;按下Esc按键&#xff0c;会【弹出】或者【隐…...

VMVareC++开发环境快速配置

OVERVIEW VMVareC开发环境快速配置ipgitvimgithubzshgcc&g&cmakesshifconfigmysqlnginxredisgdb VMVareC开发环境快速配置 VMVareC开发环境快速配置&#xff0c;为了省时间快速整理出文档方便以后快速配置&#xff0c; 按照这个流程直接可以快速得到一个舒适的C/C开发…...

数据库为什么使用B+树而不是B树做索引

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;CSDN领军人物&#xff0c;全栈领域优质创作者✌&#xff0c;CSDN博客专家&#xff0c;阿里云社区专家博主&#xff0c;2023年6月CSDN上海赛道top4。 &#x1f3c6;数年电商行业从业经验&#xff0c;历任核心研发工程师…...

java必知必会--面向对象及相关基础知识

java必知必会–面向对象及相关基础知识 一、java面向对象&#xff1a; 1、什么是面向对象以及三大特性 ①我们把数据和数据之间的相互操作关系放到一起总结为–对象。所有的操作都是基于对象来进行的。 ②面向对象的的特征&#xff1a;封装、继承、多态 ③封装&#xff1a;我…...

【推荐】Spring与Mybatis集成

目录 1.概述 2.集成 2.1代码演示&#xff1a; 3.整合 3.1概述 3.2 进行整合分页 接着上两篇&#xff0c;我已经写了Mybatis动态之灵活使用&#xff0c;mybatis的分页和特殊字符的使用方式接下来把它们集成起来&#xff0c;是如何的呢&#x1f447;&#x1f447;&#x1…...

中科驭数受邀在招商银行金融科技论坛作异构计算主题分享 解码金融科技先进算力构建之路

8月25日&#xff0c;2023招银浦江金融科技论坛正式召开。中科驭数高级副总裁张宇受邀在资管科技分论坛发表《金融行业先进异构算力底座构建之路》的主题演讲&#xff0c;与参会嘉宾分享了当前计算系统的发展趋势以及如何通过异构算力构建IT技术底座来推动金融科技的创新。 ▲ 中…...

Maven打包方式pom和jar和war的区别

Maven 项目可以使用不同的打包方式&#xff0c;如 POM、JAR 和 WAR&#xff0c;这些方式决定了项目构建后生成的产物类型和用途。下面是这些打包方式的区别&#xff1a; 1. **POM (Project Object Model)&#xff1a;** POM 打包方式实际上不会生成一个可执行的构建产物。它是…...

【51单片机】EEPROM-IIC实验(按键控制数码管)

目录 &#x1f381;I2C总线 ​编辑 &#x1f381;代码 &#x1f3f3;️‍&#x1f308;main.c &#x1f3f3;️‍&#x1f308;i2.c &#x1f386;代码分析 &#x1f381;I2C总线 I2C总线是Philips公司在八十年代初推出的一种串行、半双工的总线&#xff0c;主要用于近距…...