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

【C++】继承:万字总结

📝前言:
这篇文章我们来讲讲面向对象三大特性之一——继承

🎬个人简介:努力学习ing
📋个人专栏:C++学习笔记
🎀CSDN主页 愚润求学
🌄其他专栏:C语言入门基础,python入门基础,python刷题专栏,Linux


文章目录

  • 一,面相对象三大特性
  • 二,继承
    • 1 大白话讲继承
    • 2 继承定义格式
      • 2.1 继承方式的作用
      • 2.2 继承类模板
        • 2.2.2 需指定类域
        • 2.2.1 按需实例化
    • 3 基类和派生类间的转换
    • 4 继承中的作用域
      • 4.1 隐藏规则
    • 5 派生类的默认成员函数
    • 6 实现⼀个不能被继承的类
    • 7 友元关系不能继承
    • 8 静态成员的继承
    • 9 多继承
    • 10 继承与组合

一,面相对象三大特性

面相对象编程具有三大特性,分别是封装、继承和多态:

  • 封装
    • 概念:将数据和操作数据的方法绑定在一起,组成一个不可分割的整体,即对象。同时,对外部隐藏对象的内部实现细节,只对外提供有限的访问接口迭代器就是一种封装,底层不一样,但是却能用相似的方法访问
    • 作用:通过封装,可以提高代码的安全性和可维护性。避免外部代码直接访问和修改对象的内部数据,防止数据被意外篡改,同时也使得代码的结构更加清晰,各个模块的职责更加明确。
  • 继承
    • 概念允许创建一个新的类(子类),它基于现有的类(父类)进行扩展,子类可以继承父类的属性和方法,并且可以在子类中添加自己特有的属性和方法,或者重写父类的方法。
    • 作用:继承实现了代码的复用,避免了重复编写相似的代码。同时,它也体现了面向对象编程中的“is - a”关系,即子类是父类的一种特殊类型,有助于建立清晰的类层次结构,便于对问题域进行建模。
  • 多态
    • 概念:指同一个方法或操作在不同的对象上可以有不同的表现形式。也就是说,不同的子类对象在调用相同的方法时,可能会执行不同的代码逻辑,产生不同的结果。
    • 作用:多态提高了代码的灵活性和可扩展性。当需要添加新的功能或修改现有功能时,不需要大量修改客户端代码,只需要在相应的子类中进行修改或扩展即可。它使得代码更加易于维护和升级,同时也增强了代码的可读性和可理解性。

二,继承

1 大白话讲继承

简单来说,子类继承父类就是指:子类可以使用父类的成员,并且也可以自己加自己的成员。我们也把父类称为基类,子类称为派⽣类。
示例(下面这个程序是没有问题的):

class Person
{
public:string name;int age;char sex;
};class Student : public Person
{
public:int st_number;
};int main()
{Student st1;st1.sex = 'b';st1.st_number = 23;return 0;
}

在这里,Person是父类,Student是子类
在这里插入图片描述
通过监视窗口我们可以看到,st1里面继承了父类Person的三个成员变量。

2 继承定义格式

在这里插入图片描述

2.1 继承方式的作用

我们都知道,访问限定符有,privatepublic,和protectedprotected就是专门为继承设置的。

继承方式对应也有:privatepublic,和protected

继承类成员访问方式的变化
在这里插入图片描述

  1. 基类private成员在派⽣类中是不可见的。不可见是语法上限制派⽣类对象不管在类⾥⾯还是类外⾯都不能去访问它。(但是其实还是被继承了过去)
  2. protected成员在类外不能直接访问,在子类中可以被访问。
  3. 基类的其他成员在派⽣类的访问⽅式 == Min(成员在基类的访问限定符,继承方式)public > protected >private
  4. class默认的继承⽅式是privatestruct默认的是public,但是建议显式写出继承方式,且一般用public

如,上述代码中父类改成:

class Person
{
public:string name;private:int age;char sex;
};

这时候子类继承后,类外执行st1.sex = 'b';就会报错,因为sex是父类的私有成员

2.2 继承类模板

继承类模板需要注意的是:在子类中使用父类类模板的方法时,如果参数是不确定的,要指定一下父类的类域(才能实例化)

2.2.2 需指定类域
namespace tr
{template<class T>class stack: vector<T>{public:void push(T x){push_back(x);}};
}int main()
{tr::stack<int> st;st.push(3);return 0;
}

报错:
在这里插入图片描述
原因是:

  1. stack<int>实例化时,也实例化vector<int>了,但是不代表push_back实例化了,因为模板是按需实例化的
  2. 到了push操作,编译器要对其实例化,但是因为编译器不知道 push_backvector<T> 里的成员,从而找不到 push_back 这个标识符

正确写法:

void push(T x)
{vector<T>::push_back(x);
}
2.2.1 按需实例化

示例:

namespace tr
{template<class T>class stack: public vector<T>{public:void push(T x){push_back(x);}void print(){cout << "push_back" << endl;}};
}int main()
{tr::stack<int> st;st.print();return 0;
}

上面代码是能正常运行的,原因是实例化stack的时候,并不会把所有成员都实例化了,后面调用谁,才实例化谁。

3 基类和派生类间的转换

对象传递
当派生类对象传递给基类对象的时候,会进行切片,即:派生类对象中基类部分的数据会被复制到基类对象中,而派生类特有的成员则被 “切掉”(会丢失派生类成员的所有信息)。这时候基类对象不能访问派生类的成员,调用父类的成员时,结果也是父类对象的。
在这里插入图片描述
指针/引用传递
public继承的派生类对象的指针/引用 可以赋值基类的指针 / 基类的引用,叫向上传型,也类似做切片。传递后,基类的指针/引用指向派生类,但是只能调用派生类中的基类成员那一部分。
如:

class Person
{
public:string name;int age;char sex;
};class Student : public Person
{
public:int st_number;
};int main()
{Student st1;// 派生类对象赋值给基类的指针/引用Person* p1 = &st1;Person& p2 = st1;// 派生类对象赋值给基类对象(实际上调用的是拷贝构造)Person p3 = st1;return 0;
}

注意:基类的不能赋值给子类(基类的指针或者引⽤可以通过强制类型转换赋值给派⽣类的指针或者引⽤。但是必须是基类的指针是指向派⽣类对象时才是安全的。这⾥基类如果是多态类型,可以使⽤RTTI(Run-Time TypeInformation)的dynamic_cast 来进⾏识别后进⾏安全转换。)

4 继承中的作用域

基类和派生类都有独立的作用域

4.1 隐藏规则

隐藏:派⽣类和基类中有同名成员(即同名变量或者函数,函数只要同名就算),派⽣类成员将屏蔽基类对同名成员的直接访问。(也叫做重定义)
如果要访问被隐藏的父类成员,可以指定域。基类名::成员

示例:

class Person
{
public:void print(){cout << "Person" << endl;}string name;int age = 10;char sex;
};class Student : public Person
{
public:void print(){cout << "Student" << endl;}int age = 18;int st_number;};int main()
{Student st;cout << "st.age: " << st.age << endl; // 父类的被隐藏st.Person::print(); // 指定父类的域return 0;
}

只要函数同名就会隐藏,如下也是隐藏:
在这里插入图片描述

5 派生类的默认成员函数

我们可以派生类中的变量看出三种类型:内置类型,自定义类型,来自父类

**在子类继承父类的时候,父类的成员相当于是最先被声明的,然后才到子类自己的成员。**所以调用构造的时候也是,先父类的,再子类的

如果继承多个父类,则先继承的先声明。

  1. 派⽣类中基类的成员,必须调用基类的构造函数来初始化派生类的构造函数会自动调用基类的默认构造,所以,通常,派生类中的成员又有资源申请(需要深拷贝)的时候,我们才需要自己实现构造,拷贝构造和析构也同理)。如果基类没有默认的构造函数,则必须在派⽣类构造函数的初始化列表阶段显式调⽤(基类的构造函数)

示例(子类构造自动调用基类默认构造完成对基类成员的初始化):

class Person
{
public:Person(int age = 10) // 基类有默认构造:name("小红"),age(age),sex('b'){}void print(){cout << "Person" << endl;}string name;int age;char sex;
};class Student : public Person
{
public:Student(int number) // 子类构造自动调用父类默认构造{st_number = number;}void print(int i){cout << "Student" << endl;}int st_number;};int main()
{Student st(23);return 0;
}

在这里插入图片描述
当父类没有默认构造:

class Person
{
public:Person(int a) // 父类没有默认构造:name("小红"),age(a),sex('b'){}void print(){cout << "Person" << endl;}string name;int age;char sex;
};class Student : public Person
{
public:Student(int number){st_number = number;}void print(int i){cout << "Student" << endl;}int st_number;
};int main()
{Student st(23);return 0;
}

报错:
在这里插入图片描述
正确写法:

Student(int number, int a):Person(a) // 在初始化列表显示调用父类的默认构造
{st_number = number;
}
  1. 派⽣类的拷贝构造函数必须调用基类的拷贝构造完成对基类成员的拷贝初始化(如果这个拷贝构造不是缺省的,即不是默认构造函数,也要放在初始化列表)
  2. 派⽣类的operator=必须要调用基类的operator完成基类的复制。需要注意的是派⽣类的
    operator=隐藏了基类的operator=,所以显⽰调⽤基类的operator=,需要指定基类作⽤域
  3. 派⽣类的析构函数会在被调⽤完成后自动调用基类的析构函数清理基类成员。因为这样才能保证派⽣类对象先清理派⽣类成员再清理基类成员(后定义的先清理)的顺序
  4. 因为多态中⼀些场景析构函数需要构成重写,重写的条件之⼀是函数名相同。那么编译器会对析构函数名进⾏特殊处理,处理成destructor(),所以基类析构函数不加virtual的情况下,派生类析构函数和基类析构函数构成隐藏关系。如果要显示调用就要指定域。

示例:

class Person
{
public:Person(int a):name("小红"),age(a){}Person(const Person& p){name = p.name;age = p.age;}Person& operator=(const Person& p){if (this != &p){name = p.name;age = p.age;}return *this;}~Person(){cout << "~Person()" << endl;}string name;int age;
};class Student : public Person
{
public:Student(int number, int a):Person(a) // 在初始化列表显示调用父类的默认构造{cout << "Student(int number, int a)" << endl;st_number = number;}// 拷贝构造错误写法:/*Student(const Student& s){Person(s);st_number = s.st_number;cout << "Student(const Student& s)" << endl;}*/// 正确写法:Student(const Student& s): Person(s){st_number = s.st_number;cout << "Student(const Student& s)" << endl;}Student& operator=(const Student& s){cout << "Student& operator=(const Student& s)" << endl;if (this != &s){Person::operator=(s); // 显式调用父类的=重载来初始化父类的成员st_number = s.st_number;}return *this;}~Student(){cout << "~Student()" << endl;}int st_number;
};int main()
{Student st1(23, 18);Student st2(st1);Student st3(25, 35);st1 = st3;return 0;
}

运行结果:
在这里插入图片描述

6 实现⼀个不能被继承的类

  • ⽅法1:基类的构造函数私有,派⽣类的构成必须调⽤基类的构造函数,但是基类的构成函数私有化以后,派⽣类看不见就不能调用了,那么派生类就⽆法实例化出对象。
  • ⽅法2:C++11新增了⼀个final关键字,final修改基类(表示最终类),派⽣类就不能继承了。

示例:class Person final
在这里插入图片描述

7 友元关系不能继承

也就是说基类友元只对基类起作用,而不能访问派⽣类私有和保护成员。

8 静态成员的继承

基类定义了static静态成员,则整个继承体系⾥⾯只有⼀个这样的成员。⽆论派⽣出多少个派⽣类,都只有⼀个static成员实例,用的是用一块内存空间的static成员

9 多继承

  • 单继承:⼀个派⽣类只有⼀个直接基类

  • 多继承:⼀个派⽣类有两个或以上直接基类时称这个继承关系为多继承,多继承对象在内存中的模型是,先继承的基类在前⾯,后⾯继承的基类在后⾯,派⽣类成员在放到最后⾯。
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述

  • 菱形继承:菱形继承是多继承的⼀种特殊情况。菱形继承的问题,从下⾯的对象成员模型构造,可以看出菱形继承有数据冗余和⼆义性的问题,在Assistant的对象中Person成员会有两份。
    在这里插入图片描述

虚拟菱形继承
在菱形继承结构中,如果存在多层继承关系,使得一个派生类从两个或多个基类中继承了相同的成员,就会产生数据冗余和二义性问题。

虚拟继承就是为了解决这种问题而引入的,通过在继承关系中使用virtual关键字,使得在最终的派生类中只保留一份共享的基类子对象。

比如,在上述StudentTeacher继承时使用虚拟继承,在可能产生数据冗余和二义性的地方添加virtual,就不会产生两个name成员,在通过Assistant访问成员name时,就只有一个,不会产生二义性问题:

如果不添加:

在这里插入图片描述
添加以后:

class Person
{
public:string _name; // 姓名
// 使⽤虚继承Person类
class Student : virtual public Person
{
protected:int _num; //学号
};
// 使⽤虚继承Person类
class Teacher : virtual public Person
{
protected:int _id; // 职⼯编号
};// 教授助理
class Assistant : public Student, public Teacher
{
protected:string _majorCourse; // 主修课程
};
int main()
{
// 使⽤虚继承,可以解决数据冗余和⼆义性Assistant a;a._name = "tr";return 0;
}

10 继承与组合

  • public继承是⼀种is-a的关系。也就是说每个派⽣类对象都是⼀个基类对象。
  • 组合是⼀种has-a的关系。假设B组合了A,每个B对象中都有⼀个A对象。
  • 继承允许你根据基类的实现来定义派⽣类的实现。这种通过⽣成派⽣类的复⽤通常被称为⽩箱复⽤。“白箱”:即相对可见。在继承中,基类的内部细节对派⽣类可见,基类的改变,对派⽣类有很⼤的影响。派⽣类和基类间的依赖关系很强,耦合度⾼
  • 对象组合是类继承之外的另⼀种复⽤选择。新的更复杂的功能可以通过组装或组合对象来获得。对象组合要求被组合的对象具有良好定义的接⼝。这种复⽤⻛格被称为⿊箱复⽤(black-box reuse),因为对象的内部细节是不可⻅的。组合类之间没有很强的依赖关系,耦合度低
  • 优先使⽤对象组合有助于你保持每个类被封装,优先使⽤组合(has - a),⽽不是继承(is - 1)

🌈我的分享也就到此结束啦🌈
要是我的分享也能对你的学习起到帮助,那简直是太酷啦!
若有不足,还请大家多多指正,我们一起学习交流!
📢公主,王子:点赞👍→收藏⭐→关注🔍
感谢大家的观看和支持!祝大家都能得偿所愿,天天开心!!!

相关文章:

【C++】继承:万字总结

&#x1f4dd;前言&#xff1a; 这篇文章我们来讲讲面向对象三大特性之一——继承 &#x1f3ac;个人简介&#xff1a;努力学习ing &#x1f4cb;个人专栏&#xff1a;C学习笔记 &#x1f380;CSDN主页 愚润求学 &#x1f304;其他专栏&#xff1a;C语言入门基础&#xff0c;py…...

java和c#的相似及区别基础对比

用过十几种语言&#xff0c;但是java和c#是最为重要的两门。c#发明人曾主导开发了pascal和delphi&#xff0c;加入微软后&#xff0c;参考了c和java完成了c#和net。大家用过java或c#任意一种的&#xff0c;可以通过本篇文章快速掌握另外一门语言。 基础语法 变量声明&#xf…...

TP8 PHP 支付宝-通用版-V3 SDK 接口加签方式为证书方式

TP8 已安装支付宝-通用版-V3 SDK 接口加签方式之前使用密钥方式&#xff0c;现在要使用证书 官方文档小程序文档 - 支付宝文档中心 SDK源码仓库https://github.com/alipay/alipay-sdk-php-all/tree/master/v3 第一步&#xff1a;生成证书 需要先下载支付宝官方工具&#xff1a…...

地毯填充luogu

P1228 地毯填补问题 题目描述 相传在一个古老的阿拉伯国家里,有一座宫殿。宫殿里有个四四方方的格子迷宫,国王选择驸马的方法非常特殊,也非常简单:公主就站在其中一个方格子上,只要谁能用地毯将除公主站立的地方外的所有地方盖上,美丽漂亮聪慧的公主就是他的人了。公主…...

数据查询语言

一、DQL基础语法与执行逻辑 1.SELECT语句结构 (1)核心语法: SELECT 列名 FROM 表名 WHERE 条件 ,用于指定返回的字段和筛选行。例如, SELECT name, age FROM emp WHERE age > 25 筛选年龄大于25岁的员工姓名和年龄。 (2)执行顺序: FROM → WHERE → GROUP BY → HAV…...

【NLP】18. Encoder 和 Decoder

1. Encoder 和 Decoder 概述 在序列到序列&#xff08;sequence-to-sequence&#xff0c;简称 seq2seq&#xff09;的模型中&#xff0c;整个系统通常分为两大部分&#xff1a;Encoder&#xff08;编码器&#xff09;和 Decoder&#xff08;解码器&#xff09;。 Encoder&…...

基于Cline和OpenRouter模型进行MCP实战

大家好,我是herosunly。985院校硕士毕业,现担任算法工程师一职,获得CSDN博客之星第一名,热衷于大模型算法的研究与应用。曾担任百度千帆大模型比赛、BPAA算法大赛评委,编写微软OpenAI考试认证指导手册。曾获得多项AI顶级比赛的Top名次,其中包括阿里云、科大讯飞比赛第一名…...

Elasticsearch 故障转移及水平扩容

一、故障转移 Elasticsearch 的故障转移&#xff08;Failover&#xff09;机制是其高可用性的核心&#xff0c;通过分布式设计、自动检测和恢复策略确保集群在节点故障时持续服务。 1.1 故障转移的核心组件 组件作用Master 节点管理集群状态&#xff08;分片分配、索引创建&…...

聊聊Spring AI的Prompt

序 本文主要研究一下Spring AI的Prompt Prompt org/springframework/ai/chat/prompt/Prompt.java public class Prompt implements ModelRequest<List<Message>> {private final List<Message> messages;private ChatOptions chatOptions;public Prompt(…...

centos 7:虚拟机网络配置

1、网络模式选择 桥接模式 特点&#xff1a;虚拟机会获得与物理机同网段的独立IP&#xff0c;可直接访问内网/外网适用场景&#xff1a;渗透测试、需要与其他设备交互的场景配置要点&#xff1a;需在VMware中指定桥接到物理机的真实网卡&#xff08;如WiFi或有线网卡&#xff…...

Spring - 14 ( 5000 字 Spring 入门级教程 )

一&#xff1a;Spring原理 1.1 Bean 作用域的引入 在 Spring 的 IoC 和 DI 阶段&#xff0c;我们学习了 Spring 如何有效地管理对象。主要内容包括&#xff1a; 使用 Controller、Service、Repository、Component、Configuration 和 Bean 注解来声明 Bean 对象。通过 Applic…...

基于贝叶斯估计的多传感器数据融合算法matlab仿真

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 贝叶斯估计 4.2 多传感器数据融合 5.完整程序 1.程序功能描述 基于贝叶斯估计的多传感器数据融合算法matlab仿真&#xff0c;输入多个传感器的数据&#xff0c;通过贝叶斯估计&#xf…...

linux编辑器-vim

一、基本概念 vim有很多模式但是有三个重要的模式分别是命令模式、插入模式、低行模式。 命令模式&#xff1a;控制光标移动、字符、字或行的删除、移动、复制等。插入模式&#xff1a;只有在该模式下才可以进行文字输入。低行模式&#xff1a;文件的保存或退出&#xff0c;也…...

day27图像处理OpenCV

文章目录 一、图像预处理1 图像翻转(图像镜像旋转)2 图像仿射变换2.1 图像旋转2.2 图像平移2.3 图像缩放2.4 图像剪切 3 插值方法3.1 最近邻插值3.2 双线性插值(常用)3.3 像素区域插值--一般缩小使用3.4 双三次插值3.5 Lanczos插值 一、图像预处理 1 图像翻转(图像镜像旋转) …...

iOS开发--接入ADMob广告失败

接入ADMob的第三方广告&#xff0c;初始化时提示错误如下&#xff1a; state Not Ready;No such adapter in the application 查了各种官方文档&#xff0c;发现接入过程正确&#xff0c;查了Chatgpt和DeepSeek&#xff0c;它们各种分析&#xff0c;分析结果如下&#xff1a; …...

PyTorch进阶学习笔记[长期更新]

第一章 PyTorch简介和安装 PyTorch是一个很强大的深度学习库&#xff0c;在学术中使用占比很大。 我这里是Mac系统的安装&#xff0c;相比起教程中的win/linux安装感觉还是简单不少&#xff08;之前就已经安好啦&#xff09;&#xff0c;有需要指导的小伙伴可以评论。 第二章…...

vue3 ts 自定义指令 app.directive

在 Vue 3 中&#xff0c;app.directive 是一个全局 API&#xff0c;用于注册或获取全局自定义指令。以下是关于 app.directive 的详细说明和使用方法 app.directive 用于定义全局指令&#xff0c;这些指令可以用于直接操作 DOM 元素。自定义指令在 Vue 3 中非常强大&#xff0…...

【漫话机器学习系列】199.过拟合 vs 欠拟合(Overfit vs Underfit)

机器学习核心问题&#xff1a;过拟合 vs 欠拟合 图示作者&#xff1a;Chris Albon 1. 什么是拟合&#xff08;Fit&#xff09;&#xff1f; 拟合&#xff08;Fit&#xff09;是指模型对数据的学习效果。 理想目标&#xff1a; 在训练集上效果好 在测试集上效果也好 不复杂、…...

从0到1使用C++操作MSXML

1. 引言 MSXML&#xff08;Microsoft XML Core Services&#xff09;是微软提供的一套用于处理XML的COM组件库&#xff0c;广泛应用于Windows平台的XML解析、验证、转换等操作。本文将详细介绍如何从零开始&#xff0c;在C中使用MSXML解析和操作XML文件&#xff0c;包含完整的…...

【中间件】nginx反向代理实操

一、说明 nginx用于做反向代理&#xff0c;其目标是将浏览器中的请求进行转发&#xff0c;应用场景如下&#xff1a; 说明&#xff1a; 1、用户在浏览器中发送请求 2、nginx监听到浏览器中的请求时&#xff0c;将该请求转发到网关 3、网关再将请求转发至对应服务 二、具体操作…...

C语言中冒泡排序和快速排序的区别

冒泡排序和快速排序都是常见的排序算法&#xff0c;但它们在原理、效率和应用场景等方面存在显著区别。以下是两者的详细对比&#xff1a; 一、算法原理 1. 冒泡排序 原理&#xff1a;通过重复遍历数组&#xff0c;比较相邻元素的大小&#xff0c;并在必要时交换它们的位置。…...

进程基本介绍

进程是操作系统的重要内容,都是需要了解和学习的,那么今天我们就来好好看看. 进程基本介绍 1、Linux中,每个执行的程序都称为一个进程,每一个进程都分配一个ID号(pid,进程号). 2.每个进程都可以以两种方式存在的,前台与后台,所谓前台进程就是用户目前的屏幕上可以进行操作的,…...

通过平台大数据智能引擎及工具,构建设备管理、运行工况监测、故障诊断等应用模型的智慧快消开源了

智慧快消视频监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒&#xff0c;省去繁琐重复的适配流程&#xff0c;实现芯片、算法、应用的全流程组合&#xff0c;从而大大减少企业级应用约95%的开发成本。 基于多年的深度…...

不同数据库的注入报错信息

不同数据库在报错注入时返回的报错信息具有显著差异&#xff0c;了解这些差异可以帮助快速判断数据库类型并构造针对性的注入攻击语句。以下是主流数据库的典型报错模式及对比&#xff1a; ​ 目录 ​​ 1. MySQL​​ ​​2. Microsoft SQL Server​​ ​​3. Oracle​​ …...

tcpdump`是一个非常强大的命令行工具,用于在网络上捕获并分析数据包

通过 tcpdump&#xff0c;你可以抓取网络流量&#xff0c;诊断网络问题&#xff0c;或分析通信协议的细节。下面是如何在 Linux 上使用 tcpdump 进行抓包的详细步骤。 1. 安装 tcpdump 在大多数 Linux 发行版中&#xff0c;tcpdump 是默认安装的。如果没有安装&#xff0c;可…...

【漏洞复现】Vite 任意文件读取漏洞 CVE-2025-30208/CVE-2025-31125/CVE-2025-31486/CVE-2025-32395

Vite是什么&#xff0c;和Next.js有什么区别&#xff1f; 我上一篇文章刚介绍了Next.js漏洞的复现&#xff1a; 【漏洞复现】Next.js中间件权限绕过漏洞 CVE-2025-29927_next.js 中间件权限绕过漏洞-CSDN博客 Vite 和 Next.js 是两个不同类型的前端工具&#xff0c;它们各自…...

Odrive源码分析(六) 相关控制变量传递

本文记录下odrive源代码中相关控制模块之间变量的传递&#xff0c;这对理解odrive源代码至关重要。 通过前面文字的分析&#xff0c;odrive有两条数据链路&#xff0c;一条是通过中断进行实时的控制&#xff0c;另外一条是OS相关的操作&#xff0c;主要分析下中断内部的相关变量…...

ARM架构FFmpeg极致优化交叉编译指南

ARM架构FFmpeg极致优化交叉编译指南 一、工具链科学配置 使用最新的ARM官方工具链(Linaro或ARM GNU Toolchain) 确保工具链支持目标平台特定指令集(如NEON, VFP等) 设置正确的–sysroot和–prefix参数 1. 工具链选择原则 # 32位ARM (推荐) wget https://developer.arm.com/…...

zk源码—7.ZAB协议和数据存储一

大纲 1.两阶段提交Two-Phase Commit(2PC) 2.三阶段提交Three-Phase Commit(3PC) 3.ZAB协议算法 4.ZAB协议与Paxos算法 5.zk的数据存储原理之内存数据 6.zk的数据存储原理之事务日志 7.zk的数据存储原理之数据快照 8.zk的数据存储原理之数据初始化和数据同步流程 1.两阶…...

2025蓝桥杯C++A组省赛 题解

昨天打完蓝桥杯本来想写个 p y t h o n python python A A A 组的题解&#xff0c;结果被队友截胡了。今天上课把 C A CA CA 组的题看了&#xff0c;感觉挺简单的&#xff0c;所以来水一篇题解。 这场 B B B 是一个爆搜&#xff0c; C C C 利用取余的性质比较好写&#…...

用哪个机器学习模型 依靠极少量即时静态数据来训练ai预测足球赛的结果?

目录 一、模型推荐 1.集成树模型&#xff08;XGBoost/CatBoost&#xff09; 2.逻辑回归&#xff08;Logistic Regression&#xff09; 3.贝叶斯概率模型&#xff08;Naive Bayes或贝叶斯网络&#xff09; 4.支持向量机&#xff08;SVM&#xff09; 二、模型排除 三、训练…...

讲解贪心算法

贪心算法是一种常用的算法思想&#xff0c;其在解决问题时每一步都做出在当前状态下看起来最优的选择&#xff0c;从而希望最终能够获得全局最优解。C作为一种流行的编程语言&#xff0c;可以很好地应用于贪心算法的实现。下面我们来讲一篇关于C贪心算法的文章。 目录 贪心算法…...

0基础 | 电动汽车的“电源翻译官” | DC/DC转换器 | 电源系统三

你有没有想过&#xff0c;电动汽车里那么多五花八门的电子设备&#xff0c;比如车灯、仪表盘、摄像头&#xff0c;甚至连控制马达的“大脑”&#xff08;ECU&#xff09;&#xff0c;是怎么用上电的&#xff1f;今天就来聊聊电动车里一个默默工作的“小功臣”——DC/DC转换器&a…...

zynq7020 u-boot 速通

zynq u-boot 速通 简介 上回最小系统已经跑起来,证明串口和 ddr 正确配置.现在我们需要正确配置 网口, qspi, emmc. 网口:通过 tftp 下载 dtb,image,rootfs 在线调试.qspi:固化 boot.bin 到 qspi flash,这样 qspi 启动就可以直接运行 u-boot.emmc:存放 ubuntu_base 跟文件系统…...

C++学习之路,从0到精通的征途:string类的模拟实现

目录 一.string类的成员变量与成员函数 二.string类的接口实现 1.构造函数&#xff0c;析构函数&#xff0c;拷贝构造函数&#xff0c;赋值重载 &#xff08;1&#xff09;构造函数 &#xff08;2&#xff09;析构函数 &#xff08;3&#xff09;拷贝构造函数 &…...

网页制作中的MVC和MVT

MVC&#xff08;模型-视图-控制器&#xff09;和MVT&#xff08;模型-模板-视图&#xff09;是两种常见的软件架构模式&#xff0c;通常用于Web应用程序的设计。它们之间的主要区别在于各自的组件职责和工作方式。 MVC&#xff08;模型-视图-控制器&#xff09;&#xff1a; 模…...

02 - spring security基于配置文件及内存的账号密码

spring security基于配置的账号密码 文档 00 - spring security框架使用01 - spring security自定义登录页面 yml文件中配置账号密码 spring:security:user:name: adminpassword: 123456yml文件中配置账号密码后&#xff0c;控制台将不再输出临时密码 基于内存的账号密码 …...

Firebase Studio:开启 AI 驱动的开发新纪元

Firebase Studio&#xff08;前身为 Project IDX&#xff09;的推出&#xff0c;标志着软件开发范式正经历深刻变革。它不仅是一个传统的 IDE&#xff0c;更是一个以 AI 为主导的、代理式 (agentic) 的云端开发环境&#xff0c;专注于全栈 AI 应用&#xff08;包括 API、后端、…...

网络基础2

目录 跨网络传输流程 网络中的地址管理 - 认识 IP 地址 跨网络传输 报文信息的跨网络发送 IP地址的转化 认识端口号 端口号范围划分 源端口号和目的端口号 认识 TCP / UDP协议 理解 socket 网络字节序 socket 编程接口 sockaddr 结构 我们继续来学习网络基础 跨网…...

Maven工具学习使用(十一)——部署项目到仓库

1、使用Maven默认方式 Maven 部署项目时默认使用的上传文件方式是通过 HTTP/HTTPS 协议。要在 Maven 项目中配置部署&#xff0c;您需要在项目的 pom.xml 文件中添加 部分。这个部分定义了如何部署项目的构件&#xff08;如 JAR 文件&#xff09;到仓库。。这个部分定义了如何…...

FPGA 37 ,FPGA千兆以太网设计实战:RGMII接口时序实现全解析( RGMII接口时序设计,RGMII~GMII,GMII~RGMII 接口转换 )

目录 前言 一、设计流程 1.1 需求理解 1.2 模块划分 1.3 测试验证 二、模块分工 2.1 RGMII→GMII&#xff08;接收方向&#xff0c;rgmii_rx 模块&#xff09; 2.2 GMII→RGMII&#xff08;发送方向&#xff0c;rgmii_tx 模块&#xff09; 三、代码实现 3.1 顶层模块 …...

torch.cat和torch.stack的区别

torch.cat 和 torch.stack 是 PyTorch 中用于组合张量的两个常用函数&#xff0c;它们的核心区别在于输入张量的维度和输出张量的维度变化。以下是详细对比&#xff1a; 1. torch.cat (Concatenate) 作用&#xff1a;沿现有维度拼接多个张量&#xff0c;不创建新维度 输入要求…...

索引下推(Index Condition Pushdown, ICP)

概念 索引下推是一种数据库查询优化技术&#xff0c;通过在存储引擎层面应用部分WHERE条件来减少不必要的数据读取。它特别适用于复合索引的情况&#xff0c;因为它可以在索引扫描阶段就排除不符合全部条件的数据行&#xff0c;而不是将所有可能匹配的记录加载到服务器层再进行…...

C++基础精讲-06

文章目录 1. this指针1.1 this指针的概念1.2 this指针的使用 2. 特殊的数据成员2.1 常量数据成员2.2 引用数据成员2.3 静态数据成员2.4 对象成员 3. 特殊的成员函数3.1 静态成员函数3.2 const成员函数3.3 mutable关键字 1. this指针 1.1 this指针的概念 1.c规定&#xff0c;t…...

Django3 - 建站基础

学习开发网站必须了解网站的组成部分、网站类型、运行原理和开发流程。使用Django开发网站必须掌握Django的基本操作&#xff0c;比如创建项目、使用Django的操作指令以及开发过程中的调试方法。 一、网站的定义及组成 网站(Website)是指在因特网上根据一定的规则&#xff0c;…...

UE5蓝图设置界面尺寸大小

UE5蓝图设置界面尺寸大小 Create widget 创建UIadd to Viewport 添加视图get Game User Settings获取游戏用户设置set Screen Resolutions 设置屏幕尺寸大小1920*1080set Fullscreen Mode 设置全屏模式为&#xff1a;窗口化或者全屏Apply Settings 应用设置...

无数字字母RCE

无数字字母RCE&#xff0c;这是一个老生常谈的问题&#xff0c;就是不利用数字和字母构造出webshell&#xff0c;从而能够执行我们的命令。 <?php highlight_file(__FILE__); $code $_GET[code]; if(preg_match("/[A-Za-z0-9]/",$code)){die("hacker!&quo…...

AutoGen参数说明

UserProxyAgent用户 user_proxy = UserProxyAgent配置说明: # 构造参数 def __init__(self,name: str,is_termination_msg: Optional[Callable[[Dict], bool]] = None,max_consecutive_auto_reply: Optional[int] = None,human_input_mode: Literal["ALWAYS", &qu…...

6.2 GitHub API接口设计实战:突破限流+智能缓存实现10K+仓库同步

GitHub Sentinel 定期更新 API 接口设计 关键词:GitHub API 集成、异步爬虫开发、RESTful 接口设计、请求限流策略、数据增量更新 1. 接口架构设计原则 采用 分层隔离架构 实现数据采集与业务逻辑解耦: #mermaid-svg-WihvC78J0F5oGDbs {font-family:"trebuchet ms&quo…...

用java代码如何存取数据库的blob字段

一.业务 在业务中我们被要求将文件或图片等转成 byte[] 或 InputStream存到数据库的Blob类型的字段中. 二.Blob类型介绍 在 MySQL 中&#xff0c;Blob 数据类型用于存储二进制数据。MySQL 提供了四种不同的 Blob 类型&#xff1a; TINYBLOB: 最大存储长度为 255 个字节。BL…...