C++继承(上)
目录
一、继承的概念及定义
1. 继承的概念
2. 继承的定义
2.1 定义格式
2.2 继承关系和访问限定符
2.3 继承基类成员访问方式的变化
二、基类和派生类对象赋值转换
三、继承中的作用域
四、派生类的默认成员函数
一、继承的概念及定义
1. 继承的概念
继承是面向对象编程的三大特性之一,它允许我们在保留原有类(基类)特性的基础上进行扩展,增加新功能,从而产生新的类(派生类)。想象一下生物学的物种分类体系,就像"猫科动物"派生出"家猫"、"老虎"一样,代码中的继承可以复用已有功能。
例如,有一个 “Person” 类,它包含了人的基本信息如姓名和年龄,并有打印信息的成员函数。我们可以在其基础上派生出 “Student” 和 “Teacher” 类,这两个派生类就复用了 “Person” 类的成员变量和成员函数。通过继承,我们能构建出具有层次结构的类体系,从简单到复杂逐步扩展功能。
🌵代码示例 :
#include <iostream>
#include <string>
using namespace std;class Person
{
public:void Print(){cout << "name:" << _name << endl;cout << "age:" << _age << endl;}
protected:string _name = "ningyao"; // 姓名int _age = 18; // 年龄
};class Student : public Person
{
protected:int _stuid; // 学号
};class Teacher : public Person
{
protected:int _jobid; // 工号
};int main()
{Student s;Teacher t;s.Print();t.Print();return 0;
}
在这个例子中,“Student” 和 “Teacher” 类继承了 “Person” 类的 “Print()” 函数以及 “_name” 和 “_age” 成员变量,从而复用了其功能和数据。继承后父类的Person的成员(成员函数+成员变量)都会变成子类的一部分。这里体现出了 Student和Teacher复用了Person的成员。下面我们使用监视窗口查看Student和Teacher对象,可以看到变量的复用。调用Print可以看到成员函数的复用。
2. 继承的定义
2.1 定义格式
在 C++ 中,继承的定义形式为 :
上面我们看到Person是父类,也称作基类。Student是子类,也称作派生类。其中,继承方式(访问限定符)决定了基类成员在派生类中的访问权限。
2.2 继承关系和访问限定符
2.3 继承基类成员访问方式的变化
以 “Person” 类作为基类,“Teacher” 类作为派生类为例,不同继承方式(public、protected、private)会影响基类成员在派生类中的访问级别。例如,基类的 public 成员在 public 继承下是派生类的 public 成员,在 protected 继承下是派生类的 protected 成员,在 private 继承下是派生类的 private 成员。基类的 protected 成员在各种继承方式下都会变成派生类相应访问级别(与继承方式同级别)的成员。而基类的 private 成员在派生类中无论何种继承方式都不可见。
总结:
1. 基类private成员的不可见性
基类private成员在派生类中无论以什么方式继承都是不可见的。这里的不可见是指基类的私有成员还是被继承到了派生类对象中,但是语法上限制派生类对象不管在类里面还是类外面都不能去访问它。
class Base1 { private:int a; // 私有成员 public:int b; // 公有成员 protected:int c; // 保护成员 };class Derived1 : public Base1 { public:void test() {b = 1; // √ 可访问public成员(继承后仍为public)c = 2; // √ 可访问protected成员(继承后仍为protected)//基类private成员a存在于派生类对象内存中,但派生类内外都无法直接访问a = 3; // × 编译错误:'a' 是私有成员} };int main() {Derived1 d;d.b = 10; // √d.c = 20; // × 编译错误:protected成员不可外部访问d.a = 30; // × 编译错误:private成员不可见 }
2. protected成员的作用
基类private成员在派生类中是不能被访问,如果基类成员不想在类外直接被访问,但需要在派生类中能访问,就定义为protected。可以看出保护成员限定符是因继承才出现的。
class Base2 { protected:int value; // 保护成员 public:void setValue(int v) { value = v; } };class Derived2 : public Base2 { public:void modifyValue() {value *= 2; // √ 派生类可直接访问protected成员} };int main() {Derived2 d;d.setValue(5); // √ 通过基类public接口操作d.value = 10; // × 编译错误:不可直接访问protected成员 }
3. 访问权限计算规则
基类的私有成员在子类都是不可见。基类的其他成员在子类的访问方式 == Min(成员在基类的访问限定符,继承方式),public > protected > private。
class Base3 { public:int x; protected:int y; private:int z; };// protected继承:min(public, protected) → protected class Derived3 : protected Base3 { public:void test() {x = 1; // √ 继承后变为protectedy = 2; // √ 保持protectedz = 3; // × 编译错误} };// private继承:min(public, private) → private class Derived4 : private Base3 { public:void test() {x = 1; // √ 继承后变为privatey = 2; // √ 继承后变为private} };int main() {Derived3 d3;d3.x = 10; // × 继承后x为protectedDerived4 d4;d4.x = 10; // × 继承后x为private }
❓ 存在的疑问:
"为什么test()
能访问基类的private继承成员?这不算破坏封装性吗?"🎈 回答:
▸ 通过private继承,x
和y
已成为Derived4
自身的private成员
▸ 类的成员函数本就可以自由访问该类的任何成员(包括private)
▸ 这实际上是 白盒复用 的一种表现,不同于组合关系的黑盒复用
4. 默认继承方式差异
使用关键字class时默认的继承方式是private,使用struct时默认的继承方式是public,不过最好显示的写出继承方式。
class Base { public: int m; };// 默认public继承 struct StructDerived : Base {}; // 默认private继承 class ClassDerived : Base {}; int main() {StructDerived s;s.m = 10; // √ struct默认public继承ClassDerived c;c.m = 20; // × class默认private继承 }
5. 非public继承的局限性
在实际运用中一般使用都是public继承,几乎很少使用protetced/private继承,也不提倡使用protetced/private继承,因为protetced/private继承下来的成员都只能在派生类的类里面使用,实际中扩展维护性不强。
二、基类和派生类对象赋值转换
派生类对象 可以赋值给 基类的对象 / 基类的指针 / 基类的引用。这里有个形象的说法叫切片 或者 切割。即只保留基类部分的数据,派生类特有的数据会被丢弃。
基类对象不能直接赋值给派生类对象,因为派生类对象包含更多或更复杂的成员,基类对象无法提供这些额外的信息。
基类的指针或引用可以通过强制类型转换赋值给派生类的指针或引用,但前提是基类指针实际指向的是派生类对象,否则可能会导致越界访问等错误。
#include <iostream>
#include <string>
using namespace std;// 基类 Person
class Person
{
protected :string _name; // 姓名string _sex; // 性别int _age; // 年龄
};// 派生类 Student,继承自 Person
class Student : public Person
{
public :int _No ; // 学号
};void Test ()
{Student sobj ; // 创建 Student 对象// 1. 子类对象可以赋值给父类对象 / 指针 / 引用Person pobj = sobj ; // 子类对象赋值给父类对象,发生切片,丢失子类特有数据(_No)Person* pp = &sobj; // 父类指针指向子类对象Person& rp = sobj; // 父类引用绑定到子类对象// 2. 基类对象不能赋值给派生类对象// sobj = pobj; // 这行代码会报错,因为基类对象无法直接赋值给派生类对象// 3. 基类的指针可以通过强制类型转换赋值给派生类的指针pp = &sobj; // 父类指针指向子类对象Student* ps1 = (Student*)pp; // 强制类型转换,安全,因为 pp 实际指向 Student 对象ps1->_No = 10; // 访问并修改 Student 对象的成员变量 _Nopp = &pobj; // 父类指针指向父类对象Student* ps2 = (Student*)pp; // 强制类型转换,不安全,因为 pp 实际指向 Person 对象// ps2->_No = 10; // 此时访问 ps2->_No 会引发越界访问问题,因为 pobj 并不是 Student 对象
}int main()
{Test();return 0;
}
三、继承中的作用域
在继承体系中,基类和派生类各自拥有独立的作用域。
如果子类和父类中有同名成员,子类中的成员会屏蔽父类中同名成员的直接访问,这种情况称为隐藏。例如,子类有一个与父类同名的变量或函数,当我们试图在子类对象中访问该名称时,默认会访问子类的成员,若想访问父类的同名成员,需要使用 “基类名 :: 成员名” 的方式进行显式访问。
对于成员函数来说,只要函数名相同,无论参数是否一致,都会构成隐藏。这和函数重载不同,重载要求在同一作用域内且参数列表不同。
以下是一个关于成员变量隐藏的示例代码:
#include <iostream>
using namespace std;// 父类
class Person
{
protected:int _num = 111;
};// 子类
class Student : public Person
{
public:void fun(){cout << _num << endl; // 访问的是子类的 _num 成员变量}
protected:int _num = 999; // 子类的 _num 成员变量隐藏了父类的 _num 成员变量
};int main()
{Student s;s.fun(); // 输出 999,因为访问的是子类的 _num 成员变量return 0;
}
在这个例子中,Student
类的 _num
成员变量与 Person
类的 _num
成员变量同名。在 Student
类的 fun
函数中直接访问 _num
时,访问的是子类自己的 _num
成员变量。如果要访问父类中的 _num
成员变量,可以使用作用域限定符来显式指定:
void fun()
{cout << Person::_num << endl; // 指定访问父类中的 _num 成员变量
}
对于成员函数来说,同样存在隐藏现象。如果子类和父类中有同名的成员函数,子类的成员函数会隐藏父类中的同名成员函数。
#include <iostream>
using namespace std;// 父类
class Person
{
public:void fun(int x){cout << x << endl;}
};// 子类
class Student : public Person
{
public:void fun(double x){cout << x << endl;}
};int main()
{Student s;s.fun(3.14); // 直接调用子类中的成员函数 funs.Person::fun(20); // 指定调用父类中的成员函数 funreturn 0;
}
在上面的代码中,Student
类的 fun(double x)
成员函数隐藏了 Person
类的 fun(int x)
成员函数。当调用 s.fun(3.14)
时,调用的是子类的 fun
函数。如果要调用父类的 fun
函数,则需要使用作用域限定符 Person::
来显式指定。
需要注意的是,成员函数的隐藏只需要函数名相同即可构成隐藏,即使参数列表不同。而函数重载要求两个函数在同一作用域内,并且参数列表不同。在继承体系中,父类和子类的成员函数不在同一作用域,因此不会构成重载。
为了避免混淆和潜在的错误,在实际的继承体系设计中,应尽量避免在子类和父类中定义同名的成员变量和成员函数。如果确实需要同名成员,应清楚理解隐藏机制,并在需要访问被隐藏的父类成员时正确使用作用域限定符。
四、派生类的默认成员函数
6个默认成员函数,“默认”的意思就是指我们不写,编译器会给我们自动生成一个。
派生类成员函数的特点:
构造函数 :派生类的构造函数被调用时,会自动先调用基类的构造函数来初始化继承自基类的成员。如果基类没有默认构造函数,派生类的构造函数必须在初始化列表中显式调用基类的构造函数。例如,在
Student
类的构造函数中,通过Person(name)
显式调用基类Person
的构造函数来初始化从Person
类继承来的成员_name
。拷贝构造函数 :派生类的拷贝构造函数需要先调用基类的拷贝构造函数来完成基类部分的拷贝构造,然后再对派生类自己新增的成员进行拷贝构造。比如
Student
类的拷贝构造函数通过Person(s)
调用基类Person
的拷贝构造函数,确保基类的成员_name
被正确拷贝。赋值运算符重载函数 :派生类的赋值运算符重载函数必须先调用基类的赋值运算符重载函数来完成基类成员的赋值,再对派生类的成员进行赋值。在
Student
类的operator=
函数中,通过Person::operator=(s)
调用基类的赋值运算符重载函数,确保基类的_name
成员被正确赋值后,再对派生类的_id
成员进行赋值。析构函数 :派生类的析构函数在被调用后,会自动调用基类的析构函数来清理基类的成员。这意味着在销毁派生类对象时,先执行派生类的析构函数中的代码,清理派生类自己新增的成员,然后再自动调用基类的析构函数来清理继承自基类的成员。例如,当
Student
类的对象被销毁时,先执行~Student()
中的代码(如果有),然后自动调用~Person()
来清理_name
成员。初始化和析构顺序 :派生类对象初始化时,先调用基类的构造函数,再调用派生类的构造函数。析构时,先调用派生类的析构函数,再调用基类的析构函数。这种顺序确保了对象的构造和析构过程符合逻辑,先构造基类部分,再构造派生类部分,销毁时则相反,先销毁派生类部分,再销毁基类部分。
编写派生类默认成员函数的注意事项:
赋值运算符重载函数的隐藏问题 :由于派生类和基类的赋值运算符重载函数函数名相同,构成隐藏关系。因此,在派生类中调用基类的赋值运算符重载函数时,需要使用作用域限定符(如
Person::operator=(s)
)来显式指定调用基类的函数。析构函数的隐藏及调用 :由于多态等原因,编译器会统一对析构函数名进行特殊处理,导致派生类和基类的析构函数也构成隐藏关系。如果需要在某个地方调用基类的析构函数,必须使用作用域限定符。不过,通常情况下,我们不需要手动调用基类的析构函数,因为编译器会在派生类的析构函数执行完毕后自动调用基类的析构函数。若手动调用基类的析构函数,可能会导致基类被多次析构,引发问题。
拷贝构造函数和赋值运算符重载函数中的切片行为 :在派生类的拷贝构造函数和赋值运算符重载函数中,当将派生类对象传递给基类的拷贝构造函数或赋值运算符重载函数时,会发生切片行为,即只将派生类对象的基类部分(即从基类继承来的成员)传递给基类的函数,派生类特有的成员不会被传递。这是因为基类的拷贝构造函数和赋值运算符重载函数只能处理基类类型的对象或引用。
需要注意的是,基类的构造函数、拷贝构造函数、赋值运算符重载函数可以在派生类中通过显式调用的方式使用,但基类的析构函数在派生类的析构函数执行完毕后会由编译器自动调用,我们通常不需要手动调用基类的构造函数,否则可能导致基类被多次构造或析构的问题。
以下是一个综合示例,展示派生类中默认成员函数的调用过程。在这个例子中,当我们创建 Student
对象时,首先调用 Person
类的构造函数初始化继承的 _name
成员,然后再调用 Student
类的构造函数初始化 _id
成员。拷贝构造和赋值运算符重载函数也遵循类似的顺序,先处理基类部分,再处理派生类部分。析构时,先执行 Student
类的析构函数,再自动调用 Person
类的析构函数。
#include <iostream>
#include <string>
using namespace std;// 基类
class Person
{
public:// 构造函数Person(const string& name = "peter"): _name(name){cout << "Person()" << endl;}// 拷贝构造函数Person(const Person& p): _name(p._name){cout << "Person(const Person& p)" << endl;}// 赋值运算符重载函数Person& operator=(const Person& p){cout << "Person& operator=(const Person& p)" << endl;if (this != &p){_name = p._name;}return *this;}// 析构函数~Person(){cout << "~Person()" << endl;}
private:string _name; // 姓名
};// 派生类
class Student : public Person
{
public:// 构造函数Student(const string& name, int id): Person(name) // 调用基类的构造函数初始化基类的那一部分成员, _id(id) // 初始化派生类的成员{cout << "Student()" << endl;}// 拷贝构造函数Student(const Student& s): Person(s) // 调用基类的拷贝构造函数完成基类成员的拷贝构造, _id(s._id) // 拷贝构造派生类的成员{cout << "Student(const Student& s)" << endl;}// 赋值运算符重载函数Student& operator=(const Student& s){cout << "Student& operator=(const Student& s)" << endl;if (this != &s){Person::operator=(s); // 调用基类的 operator= 完成基类成员的赋值_id = s._id; // 完成派生类成员的赋值}return *this;}// 析构函数~Student(){cout << "~Student()" << endl;// 派生类的析构函数会在被调用完成后自动调用基类的析构函数}
private:int _id; // 学号
};int main()
{Student s1("Alice", 101); // 调用 Student 的构造函数Student s2(s1); // 调用 Student 的拷贝构造函数Student s3("Bob", 102);s3 = s1; // 调用 Student 的赋值运算符重载函数return 0;
}
相关文章:
C++继承(上)
目录 一、继承的概念及定义 1. 继承的概念 2. 继承的定义 2.1 定义格式 2.2 继承关系和访问限定符 2.3 继承基类成员访问方式的变化 二、基类和派生类对象赋值转换 三、继承中的作用域 四、派生类的默认成员函数 一、继承的概念及定义 1. 继承的概念 继承是面向对象编…...
分布式-redisson
分布式锁redisson 加锁流程缓存相关问题 加锁流程 redisson底层通过lua脚本实现加锁的原子性lock动作包含:加锁、设置超时时间、锁续命未获取到锁的线程通过获取信号量许可等待,所释放后释放信号量通知等待线程 缓存相关问题 缓存失效(击穿…...
Java学习手册:Spring MVC 架构与实现
一、Spring MVC 概述 Spring MVC 是 Spring 框架的一个模块,它提供了一套 Web 应用开发的解决方案,实现了 MVC(Model-View-Controller)设计模式。Spring MVC 提供了清晰的分离逻辑层、视图层和控制器层的结构,便于开发…...
第四部分:实用应用开发
本部分将涵盖以下关键主题: 视频处理基础 视频读取与保存视频帧处理实战:视频中运动目标追踪 条形码与二维码识别 条形码检测原理(概念)QR 码识别实战:制作二维码扫描器 文本识别入门 (OCR) 图像预处理使用 Tesseract…...
目标检测YOLO实战应用案例100讲-基于多级特征融合的小目标深度检测网络
目录 知识储备 基于多级特征融合的小目标深度检测网络实现 一、环境配置 二、核心代码实现 1. 多级特征融合模块(models/fpn.py ) 2. 主干网络(models/backbone.py ) 3. 检测头(models/detector.py ) 三、完整网络架构(models/net.py ) 四、训练代码(train.p…...
单片机-89C51部分:11、IIC 、传感器温湿度
飞书文档https://x509p6c8to.feishu.cn/wiki/Cczpw4oBeiyK71kFhKfcXkQmnad 一、简介 IIC协议,又称I2C协议,是由PHILP公司在80年代开发的两线式串行总线,用于连接微控制器及其外围设备,IIC属于半双工同步通信方式。 C IIC是一种同…...
Java从入门到精通 - Java入门
Java 入门 此笔记参考黑马教程,仅学习使用,如有侵权,联系必删 文章目录 Java 入门01 Java快速入门1. Java 是什么?能干什么?1.1 Java 背景知识1.2 Java 能做什么?1.3 Java 技术体系 2. 如何使用 Java&…...
SLAM中的状态估计理论:从基础到前沿的完整解析
SLAM中的状态估计理论:从基础到前沿的完整解析 一、SLAM状态估计基础与问题建模 1.状态估计问题的数学描述 在SLAM(Simultaneous Localization and Mapping,同时定位与地图构建)中,状态估计问题的核心在…...
Android 自带的分享功能分享到三方应用
1. 分享视频到三方应用 var shareIntent Intent(Intent.ACTION_SEND)shareIntent.setType("video/*")shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse(path))startActivity(Intent.createChooser(shareIntent, "")) 2. 分享音频到三方应用 var sha…...
宇树科技开启“人形机器人格斗盛宴”
2025年5月至6月,一场备受瞩目的全球性科技盛事——全球首届“人形机器人格斗大赛”将由杭州宇树科技隆重开启。赛事将带来前所未有的机器人格斗视觉冲击,吸引全球目光聚焦。 为打造顶级参赛队伍,宇树科技的技术精英团队已连续多周开展密集的算…...
K8S - 命名空间实战 - 从资源隔离到多环境管理
引言 在传统的物理机或虚拟机环境中,不同业务应用共享资源,容易导致权限冲突、资源争用和管理混乱。Kubernetes 通过 命名空间(Namespace)实现资源逻辑隔离,将集群划分为多个虚拟子集群,从而解决以下问题&…...
【安全扫描器原理】基于协议的服务扫描器
【安全扫描器原理】基于协议的服务扫描器 1.概述2.服务扫描的基本原理3.WWW服务扫描4.FTP服务扫描5.Telnet服务扫描1.概述 一台计算机逻辑上可以提供多项服务,每安装一个服务,即打开了一个或多个端口。从这个角度上看,每个服务对应一个或几个指定端口,反之,如果能检测到某…...
第十六届蓝桥杯 2025 C/C++组 数列差分
目录 题目: 题目描述: 题目链接: 思路: 核心算法: 思路详解: 代码: 代码详解: 题目: 题目描述: 题目链接: P12342 [蓝桥杯 2025 省 B/Py…...
模式识别的基本概念与理论体系
前面在讨论专家系统时曾经说过,为了使计算机具有自动获取知识的能力,除了应使它具有学习能力外,还应使它具有能识别诸如文字、图形、图象、声音等的能力,计算机的这种识别能力是模式识别研究的主要内容。当然,模式识别…...
机器学习,深度学习
定义(非正式):不进行明确编程的情况下,提供大量数据让计算机进行自我学习分类:监督(supervised)学习,无监督(unsupervised)学习监督学习:提供的数据中包含了问题到正确答案(x到y)的映射…...
smolagents - Guided tour
https://colab.research.google.com/github/huggingface/notebooks/blob/main/smolagents_doc/en/pytorch/guided_tour.ipynbhttps://colab.research.google.com/github/huggingface/notebooks/blob/main/smolagents_doc/en/pytorch/guided_tour.ipynb...
【keil使用】无法打开keil工程,只有空白界面的解决方法
【keil使用】无法打开keil工程,只有空白界面的解决方法 一、最常见的原因 在我们新建keil工程或下载其他大佬的keil工程的时候可能会出现工程无法正常打开的情况,如图所示: 其中最常见的一个原因就是keil工程的目录路径太长了,W…...
openEuler 22.03 安装 Nginx,支持离线安装
目录 一、环境检查1.1 必要环境检查1.2 在线安装(有网络)1.3 离线安装(无网络) 二、下载Nginx2.1 在线下载2.2 离线下载 三、安装Nginx四、开机自启服务五、开放防火墙端口六、常用命令 一、环境检查 1.1 必要环境检查 # 查看 g…...
Excel 数组功能及应用示例
Excel表格中的数组(Array)是一个可以同时存储和操作多个数据的结构。数组可以是单行、单列(一维数组)或多行多列(二维数组)。在Excel中,数组公式或动态数组功能可以一次性处理多个值,…...
C++后端服务器开发:侵入式与非侵入式程序结构解析
在C后端服务器开发中,架构设计是决定系统性能、可扩展性和可维护性的关键因素之一。尽管不同的业务需求会导致服务器架构的多样化,但网络通信模块作为所有服务的通用部分,为我们提供了一个抽象和讨论的基础。基于此,我们可以将服务…...
「Mac畅玩AIGC与多模态09」开发篇05 - 使用自定义天气查询插件开发智能体应用
一、概述 本篇介绍如何在 macOS 环境下,通过编写自定义 OpenAPI Schema,将天气查询服务接入 Dify 平台,并开发基于实时天气信息的智能体应用。本案例培养路径参数与查询参数结合的插件开发技巧,实现智能体和外部实时数据的动态联动。 二、环境准备 1. 确认本地开发环境 …...
Maven插件学习(五)—— 将项目构建生成的 OSGi Bundles(或 Features)发布到一个 P2 仓库
发布OSGi Bundles到一个 P2 仓库 读取项目中properties文件中的属性 <plugin><groupId>org.codehaus.mojo</groupId><artifactId>properties-maven-plugin</artifactId><version>1.0-alpha-2</version><executions><exec…...
欧拉计划 Project Euler61(循环的多边形数)题解
欧拉计划 Project Euler 61 题解 题干思路code 题干 思路 先生成所有四位数的多边形数集合分类保存,然后dfs找即可 code // 2512 1281 8128 2882 8256 5625 // 28684 #include <bits/stdc.h>using namespace std;using ll long long;typedef vector<i…...
C语言与Unix的传奇起源
C语言与Unix的传奇起源 背景:Multics项目的困境 这段历史要从20世纪60年代中叶的美国说起。当时,三大技术巨头——麻省理工学院(MIT)、AT&T贝尔实验室和通用电气(GE)——联手为GE-645大型机开发一个名…...
C#扩展方法与Lambda表达式基本用法
C# 扩展方法与 Lambda 表达式详解 一、扩展方法详解 1. 基本概念 扩展方法允许为现有类型"添加"方法,而无需修改原始类型或创建派生类型。 定义条件: 必须在静态类中定义方法本身必须是静态的第一个参数使用this修饰符指…...
C#规避内存泄漏的编码方法
C#规避内存泄漏的编码方法 内存泄漏是C#开发中常见的问题,尽管.NET有垃圾回收机制(GC),但不当的编码实践仍可能导致内存无法被及时回收。以下是系统性的规避内存泄漏的方法: 一、理解内存泄漏的常见原因 未释放的事件订阅静态…...
ARM 指令集(ubuntu环境学习) 第一章:ARM 指令集概述
1.1 ARM 架构简介 ARM(Advanced RISC Machine)是一种精简指令集计算机(RISC)架构,最初由英国的 ARM Holdings 公司设计。与复杂指令集计算机(CISC)不同,RISC 架构通过使用简单且高效的指令集,使得处理器能够以更高的速度和更低的功耗执行任务。ARM 架构被广泛应用于各…...
OpenCV实战教程:从零开始的计算机视觉之旅
第一部分:基础入门 OpenCV简介 什么是OpenCV及其应用领域开发环境搭建(Windows/MacOS/Linux)安装配置和第一个程序"Hello OpenCV" 图像基础 图像的数字表示方式色彩空间(RGB、HSV、灰度图)图像读取、显示与…...
零基础做自动驾驶集成测试(仿真)
图 1:使用 GPUDrive 进行极快的多代理模拟。上图:GPUDrive 中 Waymo Open Motion Dataset 场景的鸟瞰图,方框表示受控智能体,圆圈表示其目标。底部:相应的代理视图,以一个代理为中心。可以根据用户的目标轻…...
阿里云dns服务器不可用怎么办?dns可以随便改吗?
阿里云DNS服务器不可用怎么办?dns可以随便改吗? 当DNS服务器不可用时,可能导致无法访问网站或网络服务。以下是常见的解决方法: 1. 检查网络连接 确保设备已连接到互联网(如Wi-Fi或有线网络)。 尝试访问其他网站或服务&#x…...
神经网络用于地震数据时空均匀插值的方法与开源资料
神经网络用于地震数据时空均匀插值的方法与开源资料 地震数据的不均匀采样是一个常见问题,神经网络提供了一种有效的解决方案。以下是关于如何使用神经网络进行地震数据时空均匀插值的概述和可用资源。 主要方法 1. 基于深度学习的插值方法 卷积神经网络(CNN)&a…...
线性微分方程与非线性微分方程
方程一 d x d t x \frac{dx}{dt} x dtdxx 这是一个一阶线性常微分方程,可以直接分离变量求解。 将变量分离: d x x d t \frac{dx}{x} dt xdxdt 两边积分: ∫ 1 x d x ∫ 1 d t ⇒ ln ∣ x ∣ t C \int \frac{1}{x} \, dx \…...
Windows查看和修改IP,IP互相ping通
Windows系统 查看IP地址 winr 输入cmd 打开终端使用 ipconfig 或 ipconfig -all 命令查看当前网络 IPV4地址 Windows系统 修改IP地址 自动获取IP(DHCP): 打开 控制面板,点击 网络和Internet。点击 网络和共享中心。选择 更改适配…...
ESP32开发之freeRTOS的信号量
什么是信号量信号量能干啥信号量的函数实例举例总结什么是信号量 简而言之,就是发出通知,接收通知的任务获得通知后去干啥啥。通知有多有少。自定义通知数量的,叫计数型信号量;只有有无(即“0”,“1”)通知的,叫二进制信号量。 信号量能干啥 资源管理:控制多个任务对…...
CRMEB-PRO系统定时任务扩展开发指南
适用场景 当系统内置定时任务类型无法满足业务需求时,开发者可通过本教程快速掌握自定义定时任务的扩展方法。本指南以"定时检测服务"为例,演示完整开发流程。 我想添加一个定时任务 ,而这里没有我需要的,我怎么来添加 比如我想添加一个定时检…...
单片机不同通信方式的适用场景
一、串口通信 UART 通信双方约定好波特率,每次发送一个字节(8位数据) 这种通信方式一共有2根线,且互相独立不受影响。 串口通信的缺点 二、RS232和RS485 优点是能够远距离传输信号 RS232达到30m RS485达到1000m 同时RS485还具有一对多的功能 三、S…...
【神经网络与深度学习】探索全连接网络如何学习数据的复杂模式,提取高层次特征
引言 全连接网络(Fully Connected Network,FCN)是深度学习中的重要架构,广泛用于模式识别、分类和回归任务。其强大的特征提取能力使其能够自动学习输入数据中的复杂模式,并逐步形成高层次特征。这种能力主要依赖于参…...
股指期货贴水对对冲的影响大吗?
如果你持有股票,又担心股市下跌,可能会想到用股指期货来“对冲风险”——比如买入股票的同时,卖出股指期货合约。但如果股指期货处于贴水状态(期货价格低于现货价格),对冲效果会受影响吗? 一、…...
浙江大学 | DeepSeek系列公开课 | 当艺术遇见AI:科艺融合的前沿探索
今天要给大家分享一份由浙江大学出品的DeepSeek系列公开课第三季第一期,公开课的主题是当艺术遇见AI,科艺融合的新探索。本报告系统展示了浙江大学在艺术与人工智能融合领域的研究成果,涵盖古画修复流程、色彩复原技术、诗画融合模型、图像召…...
(Go Gin)Gin学习笔记(三)数据解析和绑定:结构体分析,包括JSON解析、form解析、URL解析,区分绑定的Bind方法
1. 数据解析和绑定 bind或bindXXX函数(后文中我们统一都叫bind函数)的作用就是将请求体中的参数值绑定到对应的结构体上,以方便后续业务逻辑的处理 1.1 JSON数据解析和绑定 客户端传参,后端接收并解析到结构体 package mainim…...
【JavaEE】网络原理之初识(1.0)
目录 编辑 局域网与广域网 IP地址和端口号 实现简单的服务器客户端交互 简单理解socket TCP和UDP的差别(初识) socket面对udp DatagramSocket API DatagramSocket 构造方法 DatagramSocket 方法: DatagramPacket API Data…...
Go与Cpp的本质区别
这个问题是我们经常听到的问题 常见的观点有 Go 与 C 的差异主要体现在设计哲学、内存管理、并发模型、语法特性及应用场景等方面,以下从多个维度进行详细对比: 一、内存管理机制 C:需手动管理内存(如 new/delete、智能…...
Vulkan 学习(16)---- 使用 VertexBuffer
Vertex Buffer 创建一个 VertexBuffer 存储 Vertex data,代替之前在 Shader 中使用固定顶点值的做法 Vertex Shader 修改 GLSL 的 VertexShader 如下: 注意这里指定了 input Vertex data 的 location 和 格式 #version 450 layout(location 0) in vec2 inPosit…...
论文阅读 2024 arxiv Comprehensive Assessment of Jailbreak Attacks Against LLMs
总目录 大模型安全相关研究:https://blog.csdn.net/WhiffeYF/article/details/142132328 Comprehensive Assessment of Jailbreak Attacks Against LLMs https://arxiv.org/pdf/2402.05668 https://www.doubao.com/chat/4015423571416834 速览 这篇论文是关于大…...
SIFT特征点检测
刚看完了SIFT特征点检测的原理,阅读的是两篇csdn博客,一个全面和一个最全面,不得不说,你俩写的都很全面,这么用心奉献知识的博主是全人类的财富。 现在用我这张笨拙的嘴先说一下我理解的流程 首先先将图像扩大一倍&a…...
开源模型应用落地-qwen模型小试-Qwen3-8B-快速体验-pipeline方式(二)
一、前言 阿里云最新推出的 Qwen3-8B 大语言模型,作为国内首个集成“快思考”与“慢思考”能力的混合推理模型,凭借其 80 亿参数规模及 128K 超长上下文支持,正在重塑 AI 应用边界。该模型既可通过轻量化“快思考”实现低算力秒级响应,也能在复杂任务中激活深度推理模式,以…...
Python os.path.join()路径拼接异常
问题 在使用os.path.join()对两个路径进行拼接,如:/University/School/和/Department/Class/进行拼接,最终的结果为/Department/Class/,而/University/School/却不知所踪。 import osos.path.join(“/University/School/”, “/…...
Flink之DataStream
Apache Flink 的 DataStream API 是用于 处理无限(流)或有限(批)数据流的核心编程模型,适用于事件驱动、实时分析、ETL 等场景。相比 Flink Table API,DataStream API 提供了更强的灵活性和底层控制能力。 …...
WHAT - Tailwind CSS + Antd = MetisUI组件库
文章目录 Tailwind 和 Antd 组件库MetisUI 组件库 Tailwind 和 Antd 组件库 在 WHAT - Tailwind 样式方案(不写任何自定义样式) 中我们介绍了 Tailwind,至于 Antd 组件库,我们应该都耳熟能详,官网地址:htt…...
【LLM】MOE混合专家大模型综述(重要模块原理)
note 当前的 MoE 架构就是一个用显存换训练时长/推理延迟的架构MoE 目前的架构基本集中在于将原先 GPT 每层的 FFN 复制多份作为 n 个 expert,并增加一个 router,用来计算每个 token 对应到哪个 FFN(一般采用每个 token 固定指派 n 个 exper…...