C++ 继承
目录
一、继承的概念与定义
1.1 继承的概念
1.2 继承的定义
1.2.1 语法
1.2.2 继承关系和访问限定符
1.2.3 继承基类成员访问方式的变化
二、基类和派生类对象赋值转换
三、继承中的作用域
四、派生类的默认成员函数
五、C++11 final
六、继承与友元
七、继承与静态成员
八、复杂的菱形继承及菱形虚拟继承
8.1 单继承与多继承
8.2 菱形继承
8.3 虚拟继承
九、继承与组合
一、继承的概念与定义
1.1 继承的概念
继承机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。
继承呈现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的复用都是函数复用,继承是类设计层次的复用。
例:
#include <iostream>
using namespace std;
class Person
{
public:void Print(){cout << "name:" << _name << endl;cout << "age:" << _age << endl;}
protected:string _name = "peter"; // 姓名int _age = 18;// 年龄
};
// 继承后父类的Person的成员(成员函数+成员变量)都会变成子类的一部分。
// Student和Teacher复用了Person的成员。
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类共有属性和行为_name、_age等,将这些共性内容提取出来,抽象成一个基类 Person, Student和 Teacher作为Person的派生类,复用它的_name、Print()等,并在Person的基础上根据自己的特性扩展出新的属性_stuid、_jobid,这便是继承。
1.2 继承的定义
继承是一种允许派生类(子类)继承基类(父类)的属性和方法的机制。通过继承,派生类可以重用基类的代码,同时还可以添加新的属性和方法,或者修改继承来的属性和方法。
1.2.1 语法
在C++中,使用冒号(:)来表示继承关系
class 派生类 : 访问限定符 基类
{// 类体
};
在下面这个例子中,Person 是父类/基类,Student 是子类/派生类,public 是继承方式。
class Student : public Person
{
protected:int _stuid; // 学号
};
1.2.2 继承关系和访问限定符
1.2.3 继承基类成员访问方式的变化
类成员/继承方式 | public 继承 | protected 继承 | private 继承 |
基类的 public 成员 | 派生类的 public 成员 | 派生类的 protected 成员 | 派生类的 private 成员 |
基类的 protected 成员 | 派生类的 protected 成员 | 派生类的 protected 成员 | 派生类的 private 成员 |
基类的 private 成员 | 在派生类中不可见 | 在派生类中不可见 | 在派生类中不可见 |
总结:
- . 基类 private 成员在派生类中无论以什么方式继承都是不可见的。这里的不可见是指基类的私有成员还是被继承到了派生类对象中,但是语法上限制派生类对象不管在类里面还是类外面都不能去访问它。
- 基类private成员在派生类中是不能被访问,如果基类成员不想在类外直接被访问,但需要在
派生类中能访问,就定义为 protected 。可以看出保护成员限定符是因继承才出现的。 - 基类的 protected 成员在派生类中是可以访问的,但必须通过派生类的对象来访问,而不是通过基类类型的引用或指针。
- 此表格可以一句话概括:基类的私有成员在子类不可见,基类的其他成员在子类的访问方式 == Min(成员在基类的访问限定符,继承方式)
- 在实际运用中一般使用都是 public 继承,几乎很少使用也不提倡使用 protetced/private 继承,也不提倡,因为实际中扩展维护性不强。
注意:使用关键字 class 时,默认的继承方式是 private ;使用 struct 时默认的继承方式是 public ,因此下面这种写法也可行,不过最好显示地写出继承方式。
class Student : Person // 默认私有继承,private Person
{
protected:int _stuid; // 学号
};
struct Teacher : Person // 默认公有继承,private Person
{
protected:int _jobid; // 工号
};
//不难发现,默认继承方式和class与struct的默认访问限定符是一致的
示例:
class Base
{
public:int a;
protected:int b;
private:int c;
};
class Derived1 : public Base
{// 继承后的访问方式————// public: a// protected: b// 不能访问c
};
class Derived2 : protected Base
{// 继承后的访问方式————// protected: a// protected: b// 不能访问c
};
class Derived3 : private Base
{// 继承后的访问方式————// private: a// private: b// 不能访问c
};
二、基类和派生类对象赋值转换
我们知道,double 类型可以赋值给 int类型,是因为中间生成了一个临时变量,而临时变量具有常性,所以double 类型无法赋值给 int&类型,而加上 const 后可以。
double a = 1.2;
int b = a;
int& ra = a;//报错
const int& cra = a;
与之不同的是,派生类对象可以直接赋值给 基类的对象 / 基类的指针 / 基类的引用,中间不产生临时对象,我们称之为父子类赋值兼容规则。这里有个形象的说法叫切片或者切割,寓意把派生类中父类那部分切来赋值过去。
class Person
{
protected :string _name; // 姓名string _sex; // 性别int _age; // 年龄
};class Student : public Person
{
public :int _No; // 学号
};void Test()
{Student sobj;// 1.子类对象可以赋值给父类对象/指针/引用Person pobj = sobj;Person *pp = &sobj;Person &rp = sobj;// 通过修改rp中的_name/_sex/_age可以修改sobj中的_name/_sex/_age//2.基类对象不能赋值给派生类对象sobj = pobj; //报错// 3.基类的指针可以通过强制类型转换赋值给派生类的指针pp = &sobj;Student *ps1 = (Student *) pp; // 这种情况转换时可以的。ps1->_No = 10;pp = &pobj;Student *ps2 = (Student *) pp; // 这种情况转换时虽然可以,但是会存在越界访问的问题ps2->_No = 10;
}
- 基类对象不能赋值给派生类对象
- 基类的指针或者引用可以通过强制类型转换赋值给派生类的指针或者引用。但是必须是基类的指针是指向派生类对象时才是安全的。这里基类如果是多态类型,可以使用RTTI(Run-Time Type Information)的dynamic_cast 来进行识别后进行安全转换。
注意:
- 父类子类可以有同名成员,因为它们是独立作用域。默认情况下,访问这个同名成员是直接访问子类的,子类同名成员隐藏了父类同名成员。如果要访问父类的这个成员,需要显示指定父类(在前面加上'父类::')。
- 继承中,函数同名构成隐藏,不管参数和返回值。(非函数重载,因为不在同一个作用域)
class Base
{
public:int _a = 0;int _b = 0;void func(){cout << "func()" << endl;}
};class Derived : public Base
{
public :int _a = 1;void test(){cout << _a << endl; // 1cout << Base::_a<< endl;// 0}void func(int i){cout << "func(int i)->" << i << endl;}
};int main()
{Derived d;cout << d._b << endl;;// 0d.func(1);// func(int i)-> 1d.Base::func();// func (需要指定父类)
}
三、继承中的作用域
-
在继承体系中基类和派生类都有独立的作用域。
-
若子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏,也叫重定义。(在子类成员函数中,可以使用 基类::基类成员 显示访问)
-
如果是成员函数的隐藏,只需要函数名相同就构成隐藏。
四、派生类的默认成员函数
- 如果基类有默认构造函数,派生类可以隐式调用;否则,必须在派生类构造函数初始化列表阶段显式调用基类的构造函数,并且必须先调用基类的构造函数,然后再初始化自己的成员变量。(构造:先父后子)
1. 基类有默认构造,隐式调用
class Base
{
public:Base() { cout << "Base()" << endl; }
};class Derived : public Base
{
public:Derived() {}
};int main()
{Derived d;// 打印"Base()"
}
2. 基类没有默认构造,需要显示调用基类的构造函数来初始化基类中的成员。
class Base
{
public:// 没有默认构造Base(int x): _x(x){cout << "Base(int x)->" << _x << endl;}protected:int _x;
};class Derived : public Base
{
public:Derived(int x, int y) : Base(x), _y(y) {}// 不能写成 Derived(int x, int y) :_y(y),Base(x){}private:int _y;
};
- 派生类的拷贝构造函数必须先调用基类的拷贝构造完成基类的拷贝初始化,然后再拷贝自己的成员变量。
- 派生类的operator=必须要先调用基类的operator=完成基类的复制,注意避免自我赋值。
- 取地址运算符重载在派生类中通常不需要特殊处理,除非有特殊需求。
class Base
{
public:Base(int x): _x(x){cout << "Base(int x)->" << _x << endl;}Base(const Base &b): _x(b._x){cout << "Base(const Base& b)" << endl;}Base& operator=(const Base& b){cout << "Base& operator=(const Base& b)" << endl;if (this != &b){_x = b._x;}return *this;}
protected:int _x;
};class Derived : public Base
{
public:Derived(int x, int y) : Base(x), _y(y) {}Derived(const Derived &d): Base(d),// 这里用到了基类对象和派生类的对象的赋值转换_y(d._y){cout << "Derived(const Derived &d)" << endl;}Derived& operator=(const Derived& d){cout << "Derived& operator=(const Derived& d)" << endl;if (this != &d){// 由于operator=和父类的构成隐藏,需要显示调用Base::operator=(d); // 同样的,这里也用到了赋值转换_y = d._y;}return *this;}private:int _y;
};
- 派生类的析构函数会在被调用完成后自动调用基类的析构函数清理基类成员,因此不需要显式调用基类析构。这样保证了派生类对象先清理派生类成员再清理基类成员的顺序。因此派生类对象析构清理必然是先调用派生类析构再调基类的析构。
- 由于多态的原因,析构函数统一会被处理成destructor,父子类的析构函数构成隐藏。因此即使要显式调用基类析构(错误写法),也要指定父类。
class Base
{
public:~Base(){cout << "~Base()" << endl;}
};class Derived : public Base
{
public:~Derived(){// 不需要显式调用基类析构// 如果这里显式调用 Base::~Base(); (不能写~Base();)会发现Base析构了两次cout << "~Derived()" << endl;}
};
总结: 构造先父后子,析构先子后父。(如果先构造派生类部分,而基类部分的赋值依赖于派生类部分的状态,可能会导致未定义行为,析构同理)
五、C++11 final
C++11引入 final 关键字,用于限制类的继承和函数的重写。
禁止类的继承:
class Base final {
public:void display() {std::cout << "Base class" << std::endl;}
};class Derived : public Base { // 错误:不能从final类派生void display() {std::cout << "Derived class" << std::endl;}
};
六、继承与友元
友元关系不会被继承,也就是说基类友元不能访问子类私有和保护成员。
#include <iostream>
using namespace std;class Base {int x;friend class FriendClass; // 声明FriendClass为友元
};class Derived : public Base {int y;
};class FriendClass {
public:void show(Base& b) {cout << "Base::x = " << b.x << endl; // 可以访问Base的私有成员}void show(Derived& d) {cout << "Derived::y = " << d.y << endl; // 错误:不能访问Derived的私有成员}
};int main() {Base b;Derived d;FriendClass f;f.show(b); // 正确f.show(d); // 错误return 0;
}
七、继承与静态成员
基类定义了 static 静态成员,则整个继承体系里面只有一个这样的成员。静态数据成员会被派生类继承,可以通过基类名或派生类名访问,但在内存中只有一个实例。
#include <iostream>
using namespace std;class Base {
public:static int count; // 静态数据成员,无论派生多少个都只有这一个count实例static void display() { // 静态成员函数cout << "Base::count = " << count << endl;}
};int Base::count = 0; // 静态数据成员的定义和初始化class Derived : public Base {
public:void increment() {count++; // 可以直接访问继承的静态数据成员}
};int main() {Derived d;d.increment(); // 调用派生类的成员函数,间接修改静态数据成员Derived::display(); // 通过派生类名调用继承的静态成员函数Base::display(); // 通过基类名调用静态成员函数return 0;
}
八、复杂的菱形继承及菱形虚拟继承
8.1 单继承与多继承
单继承:一个子类只有一个直接父类时称这个继承关系为单继承
多继承:一个子类有两个或以上直接父类时称这个继承关系为多继承(继承的基类之间用逗号分隔)
8.2 菱形继承
菱形继承是多继承的一种特殊情况,它涉及到一个类继承自两个派生自同一个基类的类。这种结构会导致基类在派生类中出现多次,从而引发潜在的问题,如成员变量的重复和析构函数的多次调用。
菱形继承的问题:从下面的对象成员模型构造,可以看出菱形继承有数据冗余和二义性的问题。
在 Assistant 的对象中 Person 成员会有两份。
class Person
{
public:string _name; // 姓名
};class Student : public Person
{
protected:int _num; //学号
};class Teacher : public Person
{
protected:int _id; // 职工编号
};class Assistant : public Student, public Teacher
{
protected:string _majorCourse; // 主修课程
};int main()
{// 这样会有二义性无法明确知道访问的是哪一个Assistant a;a._name = "peter";// 错误// 需要显示指定访问哪个父类的成员可以解决二义性问题,但是数据冗余问题无法解决a.Student::_name = "xxx";a.Teacher::_name = "yyy";
}
8.3 虚拟继承
为了解决菱形继承中数据冗余和二义性的问题,当一个派生类通过多条路径继承同一个基类时,可以使用 virtual 关键字来声明继承关系。这样,基类在最终派生类中只会有一个实例。注意虚拟继承不要在其他地方使用。
如上面的继承关系,在 Student 和 Teacher 的继承 Person 时使用虚拟继承,即可解决问题。
class Person
{
public:string _name; // 姓名
};
// 虚拟继承
class Student : virtual public Person
{
protected:int _num; //学号
};
// 虚拟继承
class Teacher : virtual public Person
{
protected:int _id; // 职工编号
};class Assistant : public Student, public Teacher
{
protected:string _majorCourse; // 主修课程
};int main()
{Assistant a;// 通过虚拟继承可以直接写成a._namea._name = "xxx";a.Student::_name = "yyy";a.Teacher::_name = "zzz";// 且这三种方式都修改的是同一个_name,解决了数据冗余的问题
}
虚拟继承解决数据冗余和二义性的原理:
假设有一个类A,两个类B和C都继承自A,而类D继承自B和C。且A中有成员_a,B中成员_b,C中成员_c,D中成员_d。在这种情况下,D会包含两个A的副本,一个来自B,另一个来自C。
菱形继承:借助内存窗口观察对象成员的模型,可以看到数据冗余,B和C中各有一个A。
菱形虚拟继承:
class A
{
public:int _a;
};
class B : virtual public A
{// 虚继承
public:int _b;
};
class C : virtual public A
{// 虚继承
public:int _c;
};
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;
}
通过下图发现,D对象中将A放到的了对象组成的最下面,这个A是公共的,同时属于B和C。而B和C中多出两个地址,实际上是两个指针,指向两张表。这两个指针叫虚基表指针,这两个表叫虚基表。虚基表中存的偏移量。通过偏移量就可以找到下面的A。
这里B的虚基表存的偏移量为0x14,0x005EF75C + 0x14 = 0x005EF770即A的地址;同样的,C的虚基表存的偏移量为0x0c,0x005EF764 + 0x0c = 0x005EF770。
虚拟继承是为了解决数据冗余,为什么这里使用虚拟继承后内存看起来反而变大了呢?
因为这里为了便于演示,A中只有一个int类型。假设A中有一个数组,若是菱形继承,D中就包含两个数组;若是虚拟菱形继承,只包含一个数组,内存大小自然就小了。
下面是之前的Person关系菱形虚拟继承的原理解释:
注意:在实际使用中,一般不要设计出菱形继承。 否则在复杂度及性能上都有问题。
九、继承与组合
- public继承是一种 is-a 的关系。也就是说每个派生类对象都是一个基类对象。
- 组合是一种 has-a 的关系。假设B组合了A,每个B对象中都有一个A对象。
优先使用对象组合,而不是类继承 。
- 继承允许根据基类的实现来定义派生类的实现。这种通过生成派生类的复用通常被称为白箱复用(white-box reuse)。术语“白箱”是相对可视性而言:在继承方式中,基类的内部细节对子类可见 。继承一定程度破坏了基类的封装,基类的改变,对派生类有很大的影响。派生类和基类间的依赖关系很强,耦合度高。
- 对象组合是类继承之外的另一种复用选择。新的更复杂的功能可以通过组装或组合对象来获得。对象组合要求被组合的对象具有良好定义的接口。这种复用风格被称为黑箱复用(black-box reuse),因为对象的内部细节是不可见的。对象只以“黑箱”的形式出现。组合类之间没有很强的依赖关系,耦合度低。优先使用对象组合有助于你保持每个类被封装。
// Car和BMW Car和Benz构成is-a的关系
class Car
{
protected:string _colour = "白色"; // 颜色string _num = "陕ABIT00"; // 车牌号
};class BMW : public Car
{
public:void Drive() { cout << "好开-操控" << endl; }
};class Benz : public Car
{
public:void Drive() { cout << "好坐-舒适" << endl; }
};// Tire和Car构成has-a的关系
class Tire
{
protected:string _brand = "Michelin"; // 品牌size_t _size = 17; // 尺寸
};class Car
{
protected:string _colour = "白色"; // 颜色string _num = "陕ABIT00"; // 车牌号Tire _t; // 轮胎
};
实际尽量多去用组合。组合的耦合度低,代码维护性好。不过继承也有用武之地的,有些关系就适合继承那就用继承,另外要实现多态,也必须要继承。如果类之间的关系可以用继承也可以用组合,那就用组合。
相关文章:
C++ 继承
目录 一、继承的概念与定义 1.1 继承的概念 1.2 继承的定义 1.2.1 语法 1.2.2 继承关系和访问限定符 1.2.3 继承基类成员访问方式的变化 二、基类和派生类对象赋值转换 三、继承中的作用域 四、派生类的默认成员函数 五、C11 final 六、继承与友元 七、继承与静态成…...
XSS Game(DOM型) 靶场 通关
目录 靶场网址 Ma Spaghet! 分析 解题 Jefff 分析 解题 方法一 方法二 Ugandan Knuckles 分析 解题 Ricardo Milos 分析 解题 Ah Thats Hawt 分析 解题 方法一 方法二 Ligma 分析 解题 Mafia 分析 解题 方法一:构造函数 方法二…...
XSS基础靶场练习
目录 1. 准备靶场 2. PASS 1. Level 1:无过滤 源码: 2. level2:转HTML实体 htmlspecialchars简介: 源码 PASS 3. level3:转HTML深入 源码: PASS 4. level4:过滤<> 源码: PASS: 5. level5:过滤on 源码…...
leetcode-200.岛屿数量
首先,想要找岛,肯定是要逐个遍历的,否则肯定会漏岛。 其次,我怎么知道两个点是否属于一个岛?只有一个方法,我踏上一个岛的某个点时,我就分别往四周走,且把当前地块毁掉,就…...
Linux | ubuntu安装 SSH 软件及测试工具
01 windows 要怎么和 ubuntu 互传文件呢,我们可以使用 ssh 软件。 终端输入 sudo apt-get install openssh-server ,输入登录 Ubuntu 用户的密码,这里我们输入 y 确认安装。如下图所示。 接着继续改 ssh 配置文件,因为 ssh 默认…...
组件日志——etcd
目录 一、简介 二、安装【Ubuntu】 安装etcd 安装CAPI 三、写一个示例 3.0写一个示例代码 3.1获取一个etcd服务 3.2获取租约(写端操作) 3.3使用租约(写端操作) 3.4销毁租约(写端操作) 3.5获取etcd服务中的服务列表(读端操作) 3.6监听状态变化(读端操作) 一、简介 Et…...
search_fields与filterset_fields的使用
在Django中,search_fields 和 filterset_fields 可以在视图类中使用,尤其是在 Django REST Framework (DRF) 中。它们分别用于实现搜索和过滤功能。以下是它们在视图类中的具体使用方法。 1. search_fields 在视图类中的使用 search_fields 是 DRF 中 S…...
SQLite Delete 语句详解
SQLite Delete 语句详解 SQLite 是一种轻量级的数据库管理系统,广泛应用于移动设备、嵌入式系统和服务器端应用。在数据库管理中,删除数据是一项基本操作。SQLite 提供了强大的删除功能,本文将详细介绍 SQLite 的 Delete 语句及其用法。 1.…...
通往自主智能之路:探索自我成长的AI
1. 引言:当前AI范式与自我成长智能的愿景 当前的人工智能领域在很大程度上由大型语言模型(LLM)的卓越能力所定义。这些模型,例如OpenAI的GPT系列和谷歌的BERT,已经展示了前所未有的理解和生成类人文本的能力。LLM通常…...
[自动化] 【八爪鱼】使用八爪鱼实现CSDN文章自动阅读脚本
在CSDN上,文章的阅读量往往是衡量内容影响力的一个重要指标。为了测试自动化手段能否提高阅读数,我尝试使用网页自动化工具来模拟人工阅读某个ID的文章。 1. 网页自动化的常见方案 谈到网页自动化,Selenium 是一个最常见的选择。它可以通过…...
Kafka消息序列化深度革命:构建高性能、高安全的自定义编码体系
一、突破默认序列化的桎梏 1.1 原生序列化器的致命缺陷 Kafka默认提供的StringSerializer/ByteArraySerializer在复杂场景下暴露三大痛点: 类型安全黑洞:字节流缺乏元数据描述,消费端解析如履薄冰版本兼容困境:数据结构变更导致…...
2025年如何避免使用验证码求解器时被IP封禁
引言 2025年,验证码求解器已成为自动化网络抓取和其他在线流程的关键工具。然而,自动化用户面临的一个常见挑战是IP封禁。当网站检测到自动化活动时,通常会阻止发出请求的IP地址,导致验证码挑战无法解决。本文将探讨使用验证码求…...
前端 AI IDE应用优缺点
嗯,用户问了三个前端面试的问题,我需要仔细分析每个问题,并结合提供的搜索结果来给出全面且准确的回答。 第一个问题是关于开发工具Cursor或Vim的Windurf在开发中的占比以及它们的缺点。从搜索结果里看,网页3提到了Trae对标Curso…...
银河麒麟桌面版包管理器(二)
APT包管理器 APT是Debian及其派生系统的包管理器,构建在dpkg之上,以其强大的依赖性处理能力和丰富的软件仓库而闻名。APT具有自动解决依赖关系、提供易于使用的命令行工具(如apt-get、apt-cache等),以及稳定的软件更新…...
Leetcode 3494. Find the Minimum Amount of Time to Brew Potions
Leetcode 3494. Find the Minimum Amount of Time to Brew Potions 1. 解题思路2. 代码实现 题目链接:3494. Find the Minimum Amount of Time to Brew Potions 1. 解题思路 这道题虽说算是搞定了,通过了全部的测试样例,不过还是很暴力的求…...
制作Oracle11g Docker 镜像
基于Linux系统,宿主主机要设置如下环境变量,oracle为64位版本 dockerfile中需要的数据库安装包可从csdn下载内找到 #!/bin/bash # 在宿主机上运行以设置Oracle所需的内核参数 # 这些命令需要root权限cat > /etc/sysctl.d/99-oracle.conf << EO…...
rocky linux下载软件
一、配置国内镜像源加速下载 Rocky Linux 默认使用国外软件源,国内用户可通过替换为阿里云镜像提升下载速度: 备份原配置文件: cp -r /etc/yum.repos.d /etc/yum.repos.d.backup 修改镜像源: sed -e s|^mirrorlist|#mirrorli…...
JVM的组成--运行时数据区
JVM的组成 1、类加载器(ClassLoader) 类加载器负责将字节码文件从文件系统中加载到JVM中,分为:加载、链接(验证、准备、解析)、和初始化三个阶段 2、运行时数据区 运行时数据区包括:程序计数…...
SpringBoot中安全的设置阿里云日志SLS的accessKey
众所周知,阿里云的服务都是基于accesskeyId和accesskeySecret来进行身份鉴权的,但唯独日志因为需要写入到.xml文件里对于accesskeyId和accesskeySecret需要进行一定程度的改进,尤其是使用了jasypt进行加密的参数传递进去logback.xml更是会遇到需要对参数进行解密的问题,而官网只…...
DeepSeek 助力 Vue3 开发:打造丝滑的表格(Table)之添加导出数据功能示例11,TableView15_11带分页的导出表格示例
前言:哈喽,大家好,今天给大家分享一篇文章!并提供具体代码帮助大家深入理解,彻底掌握!创作不易,如果能帮助到大家或者给大家一些灵感和启发,欢迎收藏关注哦 💕 目录 Deep…...
C++多线程编程:从创建到管理的终极指南
在高性能计算时代,掌握多线程编程是提升程序效率的必修课!本文将手把手教你如何用C++11标准库轻松创建和管理线程,告别单线程的“龟速”,让代码跑出多核CPU的性能! 一、多线程为何重要? 充分利用多核CPU:现代计算机普遍支持多核并行,多线程可让程序性能指数级提升。提升…...
人工智能算法基础
基础算法 排序查找线性结构树散列图堆栈 机器学习算法 定义:数据算法 流程:数据收集与预处理、特征选择、训练和测试模型、模型的评估。 监督学习 定义:是从给定的训练数据集中学习出一个函数,当新的数据到来时,可…...
Normal distribution (正态分布)
Normal distribution {正态分布} 1. Normal distribution (正态分布) Gaussian distribution (高斯分布)1.1. Probability density function (概率密度函数)1.2. Standard normal distribution (标准正态分布)1.3. Cumulative distribution function (累积分布函数) 2. 正态分…...
企业级前端架构设计与实战
一、架构设计核心原则 1.1 模块化分层架构 典型目录结构: src/├── assets/ # 静态资源├── components/ # 通用组件├── pages/ # 页面模块├── services/ # API服务层├── store/ # 全局状态管理├── uti…...
数据模型,数据建模,组件,核心价值,使用,意义
数据模型 一组由符号,文本组成的集合, 用以准确表达信息景观, 达到有效交流,沟通的目的 数据建模 是发现,分析和确定数据需求的过程,是一种称为数据模型的精确形式表示和传递这些需求 数据模型的组件 实体, 关系, 属性和域 数据模型的核心价值 交流性 精确性 数据模型的…...
JavaScript 比较运算符
JavaScript 比较运算符 一、基础比较运算符类型 运算符名称示例核心特性==宽松相等"5" == 5 → true隐式类型转换===严格相等"5" === 5 → false类型+值双重校验!=宽松不等null != 0 → true等效于 !(a == b)!==严格不等5 !== "5" → true类型或…...
AI Agent战国时代:Manus挑战者的破局之道与技术博弈
随着Manus引爆通用型AI Agent的"手脑协同"革命,全球AI Agent赛道进入技术竞速期。Flowith、UI-TARS、LangManus等新势力通过差异化路径重构市场格局,背后折射出开源生态、本土化创新与跨模态交互的深层技术博弈。本文结合行业权威报告与公开技…...
linux--时区查看和修改
查看当前时间和时区: 打开终端,输入以下命令查看当前的日期和时间设置: timedatectl修改时区: 使用 timedatectl 命令来修改时区: sudo timedatectl set-timezone <时区>例如,设置时区为北京时间(中国标准时间&a…...
个人博客系统 --- 测试报告
一、项目功能介绍 该项目由:登录模块、博客首页模块、博客详情页模块、博客编辑页模块四个功能模块组成。 该系统实现了个人博客的保存以及记录了发布日期、时间、发布人等信息。 二、测试内容与测试用例 我们需要对该系统进行功能测试,界面测试&…...
ESP32S3基于FreeRTOS实时操作系统控制舵机
这段代码是一个基于ESP32的舵机控制示例,通过MCPWM模块配置定时器、操作符、比较器和发生器,生成特定脉冲宽度的PWM信号,控制舵机在 -60度到60度之间以2度为步长往复转动。 1. 源码部分 #include "freertos/FreeRTOS.h" #include…...
【vue的some和filter】
在 Vue 中,some 和 filter 是两种不同的数组方法,分别用于处理数据筛选和条件判断。以下是它们在 Vue 中的具体用法和区别: 一、filter 方法 作用:对数组进行过滤,返回符合条件的新数组。 使用场景:常用于…...
【LC插件开发】基于Java实现FSRS(自由间隔重复调度算法)
😊你好,我是小航,一个正在变秃、变强的文艺倾年。 🔔本文讲解【LC插件开发】基于Java实现FSRS(自由间隔重复调度算法),期待与你一同探索、学习、进步,一起卷起来叭! 目录…...
jupyter 操作相关内容
1、jupyter界面美化 pip3 install jupyterthemes查看可用主题 jt -l推荐两个 jt -t grade3 -f consolamono -fs 140 -tfs 13 -nfs 115 -ofs 14 -cellw 90% -Tjt -t chesterish -f consolamono -fs 140 -altp -tfs 13 -nfs 115 -ofs 14 -cellw 90% -T...
【数据结构】单链表
目录 一、什么是链表?1、 定义2、链表的分类 二、无头单向非循环链表1、结构2、单链表数据的打印3、创建结点并初始化4、尾插5、头插6、尾删7、头删8、查找9、在指定位置pos之前插入数据10、在指定位置pos之后插入数据11、删除pos结点12、删除pos之后的结点13、销毁…...
UnoCSS极速入门:下一代原子化CSS引擎实战指南
文章目录 一、什么是UnoCSS?二、环境配置(Vite示例)三、核心使用模式3.1 自定义规则3.2 原子化类应用3.3 使用RegExp匹配器 四、高级功能解析4.1 主题系统4.2 响应式与深色模式 五、实战案例:构建现代按钮组件六、性能优化技巧七、…...
Es6进阶
class里的get和set 在 ES6 中,class 里的 get 和 set 是用于定义访问器属性的关键字。get 方法可在访问对象属性时调用,set 方法则在设置对象属性时调用。下面通过一个简单示例来介绍它们的用法: javascript class Person {constructor(nam…...
可发1区的创新思路:基于K-means聚类的EMD-BiLSTM-CNN-Attention时间序列预测模型(功率预测、寿命预测、流量预测、故障诊断)
首先声明,该模型为原创!原创!原创! 一、应用场景 该模型主要用于时间序列数据预测问题,包含功率预测、电池寿命预测、交通流量预测、电机故障检测等等。 二、模型整体介绍(本文以光伏功率预测为例) 核心架构 数据聚类:K-means对风电场机组分组,降低异质性干扰。…...
Android BLE 权限管理
前言 android 权限一直是比较活跃的 在蓝牙权限这一块又分新版和旧版 新版权限 android.Manifest.permission.BLUETOOTH_SCAN, android.Manifest.permission.BLUETOOTH_ADVERTISE, android.Manifest.permission.BLUETOOTH_CONNECT旧版权限如9.0以下 Manifest.permission.A…...
vue3 ts 注册全局组件
vue3 ts 注册全局组件 register.tsmain.ts register.ts // 注册全局组件 import {App} from "vue" import headerPage from "/headerPage.vue" export default {install(app:App){app.component("headerPage",headerPage)} }main.ts import re…...
Apache Doris学习
https://doris.apache.org/zh-CN/docs/gettingStarted/what-is-apache-doris 介绍 Apache Doris 是一款基于 MPP 架构(大规模并行处理)的高性能、实时分析型数据库。它以高效、简单和统一的特性著称,能够在亚秒级的时间内返回海量数据的查询…...
llama源码学习·model.py[7]Transformer类
一、源码展示 class Transformer(nn.Module):def __init__(self, params: ModelArgs):super().__init__()self.params paramsself.vocab_size params.vocab_sizeself.n_layers params.n_layersself.tok_embeddings VocabParallelEmbedding(params.vocab_size, params.dim,…...
Windows server 2022域控制服务器的配置
Windows server 2022介绍 一、核心特性与改进 安全核心服务器(Secured-Core Server) 硬件级安全:支持基于硬件的安全功能(如TPM 2.0、Secure Boot、基于虚拟化的安全防护VBS),防止固件攻击。受信任的启动链…...
yolo目标检测算法在DJI上的研究分析(大纲)
yolo目标检测算法在DJI上的研究分析 面向边缘计算的实时目标检测系统设计与部署 第一章 绪论 1.1 研究背景与意义 目标检测技术需求: DJI设备(如无人机、摄像头)在安防、巡检、农业等场景中的广泛应用现有YOLO算法在高分辨率图像或资源受限…...
三、重学C++—C语言内存管理
上一章节: 二、重学C—C语言核心-CSDN博客https://blog.csdn.net/weixin_36323170/article/details/146191640?spm1001.2014.3001.5502 本章节代码: cPart2 CuiQingCheng/cppstudy - 码云 - 开源中国https://gitee.com/cuiqingcheng/cppstudy/tree/…...
DAY37 动态归化Ⅰ基础题目
509. 斐波那契数 - 力扣(LeetCode) class Solution { public:int fib(int n) {if(n<1) return n;int dp[2];dp[0]0;dp[1]1;int sum0;for(int i2;i<n;i){sum dp[0]dp[1];dp[0]dp[1];dp[1]sum;}return sum;} }; 70. 爬楼梯 - 力扣(Lee…...
ABAP Core Data Services (SAP PRESS) (First Edition)
ABAP Core Data Services (SAP PRESS) (First Edition)...
ORM——对象关系映射
对象关系映射(ORM)深度解析:原理、优势与应用场景 一、什么是ORM? ORM(Object-Relational Mapping)即对象关系映射,是一种将面向对象编程中的对象与关系型数据库中的表进行映射的技术。简单来…...
【Docker系列五】Docker Compose 简介
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
大语言模型-2.2/3-主流模型架构与新型架构
简介 本博客内容是《大语言模型》一书的读书笔记,该书是中国人民大学高瓴人工智能学院赵鑫教授团队出品,覆盖大语言模型训练与使用的全流程,从预训练到微调与对齐,从使用技术到评测应用,帮助学员全面掌握大语言模型的…...
JAVA组件的利用漏洞 Shlr搜索引擎 shiro身份 Log4j日志
solr组件 1、作用 : 基于http和apache lucene 进行全文搜索服务器 2、识别: 第一个就是图标类似于华为的那个 然后就是端口标识是 8983 3、CVE利用: 1、命令执行(CVE-2019-17558) Apache Solr 5.0.0版本至8…...