c++(继承、模板进阶)
一、模板进阶
1、非类型模板参数
模板参数分类类型形参与非类型形参。
类型形参即:出现在模板参数列表中,跟在class或者typename之类的参数类型名称。
非类型形参,就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中可将该参数当成常
量来使用。
namespace arr
{// 定义一个模板类型的静态数组template<class T, size_t N = 10>class array{public:T& operator[](size_t index) { return _array[index]; }const T& operator[](size_t index)const { return _array[index]; }size_t size()const { return _size; }bool empty()const { return 0 == _size; }private:T _array[N];size_t _size;};
}
2、模板的特化
通常情况下,使用模板可以实现一些与类型无关的代码,但对于一些特殊类型的可能会得到一些
错误的结果,需要特殊处理,比如:实现了一个专门用来进行小于比较的函数模板
class Date
{
public:Date(int year, int month, int day):_year(year){}bool operator<(Date& d){return _year < d._year;}
private:int _year = 0;
};
template<class T>
bool Less(T left, T right)
{return left < right;
}
int main()
{cout << Less(1, 2) << endl; // 可以比较,结果正确Date d1(2022, 7, 7);Date d2(2022, 7, 8);cout << Less(d1, d2) << endl; // 可以比较,结果正确Date* p1 = &d1;Date* p2 = &d2;cout << Less(p1, p2) << endl; // 可以比较,结果错误return 0;
}
可以看到,Less绝对多数情况下都可以正常比较,但是在特殊场景下就得到错误的结果。上述示
例中,p1指向的d1显然小于p2指向的d2对象,但是Less内部并没有比较p1和p2指向的对象内
容,而比较的是p1和p2指针的地址,这就无法达到预期而错误。
此时,就需要对模板进行特化。即:在原模板类的基础上,针对特殊类型所进行特殊化的实现方
式。模板特化中分为函数模板特化与类模板特化。
函数模板的特化步骤:
-
必须要先有一个基础的函数模板
-
关键字template后面接一对空的尖括号<>
-
函数名后跟一对尖括号,尖括号中指定需要特化的类型
-
函数形参表: 必须要和模板函数的基础参数类型完全相同,如果不同编译器可能会报一些奇
怪的错误。
template<class T>
bool Less(T left, T right)
{return left < right;
}
// 对Less函数模板进行特化
template<>
bool Less<Date*>(Date* left, Date* right)
{return *left < *right;
}
int main()
{cout << Less(1, 2) << endl;Date d1(2022, 7, 7);Date d2(2022, 7, 8);cout << Less(d1, d2) << endl;Date* p1 = &d1;Date* p2 = &d2;cout << Less(p1, p2) << endl; // 调用特化之后的版本,而不走模板生成了return 0;
}
注意:一般情况下如果函数模板遇到不能处理或者处理有误的类型,为了实现简单通常都是将该
函数直接给出
bool Less(Date* left, Date* right)
{return *left < *right;
}
该种实现简单明了,代码的可读性高,容易书写,因为对于一些参数类型复杂的函数模板,特化
时特别给出,因此函数模板不建议特化。
3、类模板特化
1、全特化
全特化即是将模板参数列表中所有的参数都确定化。
template<class T1, class T2>
class Data
{
public:Data() { cout << "Data<T1, T2>" << endl; }
private:T1 _d1;T2 _d2;
};
template<>
class Data<int, char>
{
public:Data() { cout << "Data<int, char>" << endl; }
private:int _d1;char _d2;
};
void TestVector()
{Data<int, int> d1;Data<int, char> d2;
}
2、偏特化
偏特化:任何针对模版参数进一步进行条件限制设计的特化版本。比如对于以下模板类:
template<class T1, class T2>
class Data
{public:Data() {cout<<"Data<T1, T2>" <<endl;}private:T1 _d1;T2 _d2;
};
偏特化有以下两种表现方式:
部分特化
将模板参数类表中的一部分参数特化。
// 将第二个参数特化为int
template <class T1>
class Data<T1, int>
{public:Data() {cout<<"Data<T1, int>" <<endl;}private:T1 _d1;int _d2;
};
参数更进一步的限制
偏特化并不仅仅是指特化部分参数,而是针对模板参数更进一步的条件限制所设计出来的一
个特化版本。
//两个参数偏特化为指针类型
template <typename T1, typename T2>
class Data <T1*, T2*>
{
public:Data() { cout << "Data<T1*, T2*>" << endl; }
private:T1 _d1;T2 _d2;
};
//两个参数偏特化为引用类型
template <typename T1, typename T2>
class Data <T1&, T2&>
{
public:Data(const T1& d1, const T2& d2): _d1(d1), _d2(d2){cout << "Data<T1&, T2&>" << endl;}
private:const T1& _d1;const T2& _d2;
};
void test2()
{Data<double, int> d1; // 调用特化的int版本Data<int, double> d2; // 调用基础的模板Data<int*, int*> d3; // 调用特化的指针版本Data<int&, int&> d4(1, 2); // 调用特化的指针版本
}
二、继承
1、概念
继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许我们在保持原有
类特性的基础上进行扩展,增加方法(成员函数)和属性(成员变量),这样产生新的类,称子类。继承呈
现了面向对象程序设计的层次结构,体现了由简单到复杂的认知过程。以前我们接触的函数层次的复
用,继承是类设计层次的复用。
下面我们看到没有继承之前我们设计了两个类Student和Teacher,Student和Teacher都有姓名/地址/
电话/年龄等成员变量,都有identity身份认证的成员函数,设计到两个类里面就是冗余的。当然他们
也有⼀些不同的成员变量和函数,比如老师独有成员变量是职称,学生的独有成员变量是学号;学生
的独有成员函数是学习,老师的独有成员函数是授课。
#include<iostream>
#include<string>
using namespace std;
class Student
{
public:// 进⼊校园/图书馆/实验室刷⼆维码等⾝份认证void identity(){// ...}// 学习void study(){// ...}
protected:string _name = "peter"; // 姓名string _address; // 地址string _tel; // 电话int _age = 18; // 年龄int _stuid; // 学号
};
class Teacher
{
public:// 进⼊校园/图书馆/实验室刷⼆维码等⾝份认证void identity(){// ...}// 授课void teaching(){//...}
protected:string _name = "张三"; // 姓名int _age = 18; // 年龄string _address; // 地址string _tel; // 电话string _title; // 职称
};
int main()
{return 0;
}
下面我们公共的成员都放到Person类中,Student和teacher都继承Person,就可以复用这些成员,就
不需要重复定义了,省去了很多麻烦。
class Person
{
public:// 进⼊校园/图书馆/实验室刷⼆维码等⾝份认证void identity(){cout << "void identity()" << _name << endl;}
protected:string _name = "张三"; // 姓名string _address; // 地址string _tel; // 电话int _age = 18; // 年龄
};
class Student : public Person
{
public:// 学习void study(){// ...}protected:int _stuid; // 学号
};
class Teacher : public Person
{
public:// 授课void teaching(){//...}
protected:string title; // 职称
};
int main()
{Student s;Teacher t;s.identity();t.identity();return 0;
}
2、继承定义
a、定义格式:
下面我们看到Person是父类,也称作基类。Student是子类,也称作派生类。(因为翻译的原因,所以
既叫父类/子类,也叫父类/子类)
3、继承父类成员访问方式的变化
- 父类private成员在子类中无论以什么方式继承都是不可见的。这里的不可见是指父类的私有成员还
是被继承到了子类对象中,但是语法上限制子类对象不管在里面还是类外面都不能去访问它。
- 父类private成员在子类中是不能被访问,如果父类成员不想在类外直接被访问,但需要在子类中能
访问,就定义为protected。可以看出保护成员限定符是因继承才出现的。
- 实际上面的表格我们进行⼀下总结会发现,父类的私有成员在子类都是不可见。父类的其他成员在
子类的访问方式 == Min(成员在父类的访问限定符,继承方式),public > protected > private。
- 使用关键字class时默认的继承方式是private,使用struct时默认的继承方式是public,不过最好显
示的写出继承方式。
- 在实际运用中⼀般使用都是public继承,几乎很少使用protetced/private继承,也不提倡使用
protetced/private继承,因为protetced/private继承下来的成员都只能在子类的类里面使用,实际
中扩展维护性不强。
// 实例演⽰三种继承关系下父类成员的各类型成员访问关系的变化
class Person
{
public:void Print(){cout << _name << endl;}
protected:string _name; // 姓名
private:int _age; // 年龄
};
//class Student : protected Person
//class Student : private Person
class Student : public Person
{
protected:int _stunum; // 学号
};
4、继承类模板
#include<iostream>
#include<vector>
using namespace std;
template<class T>
class stack :public vector<T>
{
public:void push(const T t){vector<T>::push_back(t);}void pop(){vector<T>::pop_back();}const T& top(){return vector<T>::back();}
};
int main()
{stack<int> st;st.push(1);st.push(1);st.push(1);st.push(1);for (auto& it : st){cout << it;}return 0;
}
5、父类和子类对象赋值兼容转换
public继承的子类对象 可以赋值给 父类的对象 / 父类的指针 / 父类的引用。这里有个形象的说法叫
切片或者切割。寓意把子类中父类那部分切来赋值过去。
父类对象不能赋值给子类对象。
父类的指针或者引用可以通过强制类型转换赋值给子类的指针或者引用。但是必须是父类的指针是
指向子类对象时才是安全的。这里父类如果是多态类型,可以使用RTTI(Run-Time Type
Information)的dynamic_cast 来进行识别后进行安全转换。
class Person
{
protected:string _name; // 姓名string _sex; // 性别int _age; // 年龄
};
class Student : public Person
{
public:int _No; // 学号
};
int main()
{Student sobj;// 1.子类对象可以赋值给父类对象/指针/引用Person pobj = sobj;Person * pp = &sobj;Person & rp = sobj;//2.父类对象不能赋值给子类对象,这⾥会编译报错sobj = pobj;return 0;
}
6、继承中的作用域
a、隐藏规则
-
在继承体系中父类和子类都有独⽴的作用域。
-
子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏。(在子类成员函数中,可以使用父类::父类成员 显示访问)
-
需要注意的是如果是成员函数的隐藏,只需要函数名相同就构成隐藏。
-
注意在实际中在继承体系里面最好不要定义同名的成员。
// Student的_num和Person的_num构成隐藏关系,可以看出这样代码虽然能跑,但是⾮常容易混淆
class Person
{
protected:string _name = "⼩李子"; // 姓名int _num = 111; // ⾝份证号
};
class Student : public Person
{
public:void Print(){cout << " 姓名:" << _name << endl;cout << " ⾝份证号:" << Person::_num << endl;cout << " 学号:" << _num << endl;}
protected:int _num = 999; // 学号
};
int main()
{Student s1;s1.Print();return 0;
}
7、子类的默认成员函数
a、四个常见的默认构造函数
- 子类的构造函数必须调用父类的构造函数初始化父类的那⼀部分成员。如果父类没有默认的构造函
数,则必须在子类构造函数的初始化列表阶段显示调用。
-
子类的拷贝构造函数必须调用父类的拷贝构造完成父类的拷贝初始化。
-
子类的operator=必须要调用父类的operator=完成父类的复制。需要注意的是子类的operator=隐
藏了父类的operator=,所以显示调用父类的operator=,需要指定父类作用域
- 子类的析构函数会在被调用完成后⾃动调用父类的析构函数清理父类成员。因为这样才能保证子类
对象先清理子类成员再清理父类成员的顺序。
-
子类对象初始化先调用父类构造再调子类构造。
-
子类对象析构清理先调用子类析构再调父类的析构。
class Person
{
public:Person(const char* 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;}
protected:string _name; // 姓名
};
class Student : public Person
{
public:Student(const char* name, int num): Person(name), _num(num){cout << "Student()" << endl;}Student(const Student & s): Person(s), _num(s._num){cout << "Student(const Student& s)" << endl;}Student & operator = (const Student & s){cout << "Student& operator= (const Student& s)" << endl;if (this != &s){// 构成隐藏,所以需要显⽰调用Person::operator =(s);_num = s._num;}return *this;}~Student(){cout << "~Student()" << endl;}
protected:int _num; //学号
};
int main()
{Student s1("jack", 18);Student s2(s1);Student s3("rose", 17);s1 = s3;return 0;
}
8、继承与友元
友元关系不能继承,也就是说父类友元不能访问子类私有和保护成员 。
class Person
{
public:friend void Display(const Person & p, const Student & s);
protected:string _name; // 姓名
};
class Student : public Person
{
protected:int _stuNum; // 学号
};
void Display(const Person & p, const Student & s)
{cout << p._name << endl;cout << s._stuNum << endl;
}
int main()
{Person p;Student s;// 编译报错:error C2248: “Student::_stuNum”: ⽆法访问 protected 成员// 解决⽅案:Display也变成Student 的友元即可Display(p, s);return 0;
}
9、继承与静态成员
父类定义了static静态成员,则整个继承体系里面只有⼀个这样的成员。无论派生出多少个子类,都只
有⼀个static成员实例。
class Person
{
public:string _name;static int _count;
};
int Person::_count = 0;
class Student : public Person
{
protected:int _stuNum;
};
int main()
{Person p;Student s;// 这⾥的运⾏结果可以看到⾮静态成员_name的地址是不⼀样的// 说明子类继承下来了,父子类对象各有⼀份cout << &p._name << endl;cout << &s._name << endl;// 这⾥的运⾏结果可以看到静态成员_count的地址是⼀样的// 说明子类和父类共用同⼀份静态成员cout << &p._count << endl;cout << &s._count << endl;// 公有的情况下,父子类指定类域都可以访问静态成员cout << Person::_count << endl;cout << Student::_count << endl;return 0;
}
10、继承模型
单继承:⼀个子类只有⼀个直接父类时称这个继承关系为单继承
多继承:⼀个子类有两个或以上直接父类时称这个继承关系为多继承,多继承对象在内存中的模型
是,先继承的父类在前面,后面继承的父类在后面,子类成员在放到最后面。
菱形继承:菱形继承是多继承的⼀种特殊情况。菱形继承的问题,从下面的对象成员模型构造,可以
看出菱形继承有数据冗余和⼆义性的问题,在Assistant的对象中Person成员会有两份。⽀持多继承就
⼀定会有菱形继承,像Java就直接不⽀持多继承,规避掉了这⾥的问题,所以实践中我们也是不建议
设计出菱形继承这样的模型的。
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()
{// 编译报错:error C2385: 对“_name”的访问不明确Assistant a;a._name = "peter";// 需要显⽰指定访问哪个父类的成员可以解决⼆义性问题,但是数据冗余问题⽆法解决a.Student::_name = "xxx";a.Teacher::_name = "yyy";return 0;
}
11、虚继承
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._name = "peter";a.Student::_name = "xxx";a.Teacher::_name = "yyy";return 0;
}
12、继承与组合
• public继承是⼀种is-a的关系。也就是说每个子类对象都是⼀个父类对象。
• 组合是⼀种has-a的关系。假设B组合了A,每个B对象中都有⼀个A对象。
• 继承允许你根据父类的实现来定义子类的实现。这种通过⽣成子类的复用通常被称为白箱复用
(white-box reuse)。术语“白箱”是相对可视性而言:在继承方式中,父类的内部细节对子类可见
。继承⼀定程度破坏了父类的封装,父类的改变,对子类有很大的影响。子类和父类间的依赖关系
很强,耦合度高。
• 对象组合是类继承之外的另⼀种复用选择。新的更复杂的功能可以通过组装或组合对象来获得。对
象组合要求被组合的对象具有良好定义的接⼝。这种复用风格被称为黑箱复用(black-box reuse),
因为对象的内部细节是不可见的。对象只以“黑箱”的形式出现。 组合类之间没有很强的依赖关
系,耦合度低。优先使用对象组合有助于你保持每个类被封装。
• 优先使用组合,而不是继承。实际尽量多去用组合,组合的耦合度低,代码维护性好。不过也不太
那么绝对,类之间的关系就适合继承(is-a)那就用继承,另外要实现多态,也必须要继承。类之间的
关系既适合用继承(is-a)也适合组合(has-a),就用组合。
• 很多⼈说C++语法复杂,其实多继承就是⼀个体现。有了多继承,就存在菱形继承,有了菱形继承
就有菱形虚拟继承,底层实现就很复杂,性能也会有⼀些损失,所以最好不要设计出菱形继承。
12、继承与组合
• public继承是⼀种is-a的关系。也就是说每个子类对象都是⼀个父类对象。
• 组合是⼀种has-a的关系。假设B组合了A,每个B对象中都有⼀个A对象。
• 继承允许你根据父类的实现来定义子类的实现。这种通过⽣成子类的复用通常被称为白箱复用
(white-box reuse)。术语“白箱”是相对可视性而言:在继承方式中,父类的内部细节对子类可见
。继承⼀定程度破坏了父类的封装,父类的改变,对子类有很大的影响。子类和父类间的依赖关系
很强,耦合度高。
• 对象组合是类继承之外的另⼀种复用选择。新的更复杂的功能可以通过组装或组合对象来获得。对
象组合要求被组合的对象具有良好定义的接⼝。这种复用风格被称为黑箱复用(black-box reuse),
因为对象的内部细节是不可见的。对象只以“黑箱”的形式出现。 组合类之间没有很强的依赖关
系,耦合度低。优先使用对象组合有助于你保持每个类被封装。
• 优先使用组合,而不是继承。实际尽量多去用组合,组合的耦合度低,代码维护性好。不过也不太
那么绝对,类之间的关系就适合继承(is-a)那就用继承,另外要实现多态,也必须要继承。类之间的
关系既适合用继承(is-a)也适合组合(has-a),就用组合。
• 很多⼈说C++语法复杂,其实多继承就是⼀个体现。有了多继承,就存在菱形继承,有了菱形继承
就有菱形虚拟继承,底层实现就很复杂,性能也会有⼀些损失,所以最好不要设计出菱形继承。多
继承可以认为是C++的缺陷之⼀,后来的⼀些编程语⾔都没有多继承,如Java。
相关文章:

c++(继承、模板进阶)
一、模板进阶 1、非类型模板参数 模板参数分类类型形参与非类型形参。 类型形参即:出现在模板参数列表中,跟在class或者typename之类的参数类型名称。 非类型形参,就是用一个常量作为类(函数)模板的一个参数,在类(函数)模板中…...

【机器学习】从零开始理解深度学习——揭开神经网络的神秘面纱
1. 引言 随着技术的飞速发展,人工智能(AI)已从学术研究的实验室走向现实应用的舞台,成为推动现代社会变革的核心动力之一。而在这一进程中,深度学习(Deep Learning)因其在大规模数据处理和复杂问题求解中的卓越表现,迅速崛起为人工智能的最前沿技术。深度学习的核心是…...

WebLogic 笔记汇总
WebLogic 笔记汇总 一、weblogic安装 1、创建用户和用户组 groupadd weblogicuseradd -g weblogic weblogic # 添加用户,并用-g参数来制定 web用户组passwd weblogic # passwd命令修改密码# 在文件末尾增加以下内容 cat >>/etc/security/limits.conf<<EOF web…...

leetcode:2710. 移除字符串中的尾随零(python3解法)
难度:简单 给你一个用字符串表示的正整数 num ,请你以字符串形式返回不含尾随零的整数 num 。 示例 1: 输入:num "51230100" 输出:"512301" 解释:整数 "51230100" 有 2 个尾…...

Python GUI入门详解-学习篇
一、简介 GUI就是图形用户界面的意思,在Python中使用PyQt可以快速搭建自己的应用,自己的程序看上去就会更加高大上。 有时候使用 python 做自动化运维操作,开发一个简单的应用程序非常方便。程序写好,每次都要通过命令行运行 pyt…...

QT5实现https的post请求(QNetworkAccessManager、QNetworkRequest和QNetworkReply)
QT5实现https的post请求 前言一、一定要有sslErrors处理1、问题经过2、代码示例 二、要利用抓包工具1、问题经过2、wireshark的使用3、利用wireshark查看服务器地址4、利用wireshark查看自己构建的请求报文 三、返回数据只能读一次1、问题描述2、部分代码 总结 前言 QNetworkA…...

vscode 使用git bash,路径分隔符缺少问题
window使用bash --login -i 使用bash时候,在系统自带的terminal里面进入,测试conda可以正常输出,但是在vscode里面输入conda发现有问题 bash: C:\Users\marswennaconda3\Scripts: No such file or directory实际路径应该要为 C:\Users\mars…...

F12抓包10:UI自动化 - Elements(元素)定位页面元素
课程大纲 1、前端基础 1.1 元素 元素是构成HTML文档的基本组成部分之一,定义了文档的结构和内容,比如段落、标题、链接等。 元素大致分为3种:基本结构、自闭合元素(self-closing element)、嵌套元素。 1、基本结构&…...

android 删除系统原有的debug.keystore,系统运行的时候,重新生成新的debug.keystore,来完成App的运行。
1、先上一个图:这个是keystore无效的原因 之前在安装这个旧版本android studio的时候呢,安装过一版最新的android studio,然后通过模拟器跑过测试的demo。 2、运行旧的项目到模拟器的时候,就报错了: Execution failed…...

SQL入门题
作者SQL入门小白,此栏仅是记录一些解题过程 1、题目 用户访问表users,记录了用户id(usr_id)和访问日期(log_date),求出连续3天以上访问的用户id。 2、解答过程 2.1数据准备 通过navicat创建数据…...

Python实战:实战练习案例汇总
Python实战:实战练习案例汇总 **Python世界系列****Python实践系列****Python语音处理系列** 本文逆序更新,汇总实践练习案例。 Python世界系列 Python世界:力扣题43大数相乘算法实践Python世界:求解满足某完全平方关系的整数实…...

zabbix之钉钉告警
钉钉告警设置 我们可以将同一个运維组的人员加入到同一个钉钉工作群中,当有异常出现后,Zabbix 将告警信息发送到钉钉的群里面,此时,群内所有的运维人员都能在第一时间看到这则告警详细。 Zabbix 监控系统默认没有开箱即用…...

《OpenCV计算机视觉》—— 对图片进行旋转的两种方法
文章目录 一、用numpy库中的方法对图片进行旋转二、用OpenCV库中的方法对图片进行旋转 一、用numpy库中的方法对图片进行旋转 numpy库中的 np.rot90 函数方法可以对图片进行旋转 代码实现如下: import cv2 import numpy as np# 读取图片 img cv2.imread(wechat.jp…...

Python 错误 ValueError 解析,实际错误实例详解 (一)
文章目录 前言Python 中错误 ValueError: No JSON object Could Be Decoded在 Python 中解码 JSON 对象将 JSON 字符串解码为 Python 对象将 Python 对象编码为 JSON 字符串Python 中错误 ValueError: Unsupported Pickle Protocol: 3Python 中的 Pickling 和 UnpicklingPython…...

[java][git]上传本地代码及更新代码到GitHub教程
上传本地代码及更新代码到GitHub教程 上传本地代码 第一步:去github上创建自己的Repository,创建页面如下图所示: 红框为新建的仓库的https地址 第二步: echo "# Test" >> README.md 第三步:建立g…...

react antd table expandable defaultExpandAllRows 不生效问题
原因:defaultExpandAllRows只会在第一次渲染时触发 解决方案:渲染前判断table 的datasource 数据是否已准备好 {pageList.length > 0 ? (<TablerowSelection{rowSelection}columns{columns}dataSource{pageList}style{{ marginTop: 24 }}pagina…...

什么是领域驱动设计?
什么是领域驱动设计? 领域驱动设计(Domain-Driven Design,简称DDD)是一种面向对象的软件开发方法,它强调将软件系统的设计和实现过程与业务领域紧密结合,通过深入理解和建模业务领域,从而实现高…...

信息安全工程师(1)计算机网络分类
一、按分布范围分类 广域网(WAN): 定义:广域网的任务是提供长距离通信,运送主机所发送的数据。其覆盖范围通常是直径为几十千米到几千千米的区域,因此也被称为远程网。特点:连接广域网的各个结点…...

利士策分享,探索无界:心灵之旅,发现未知精彩
利士策分享,探索无界:心灵之旅,发现未知精彩 梦想的种子,在心田生根发芽 正如每一颗种子都蕴含着生命的奥秘,每个人心中那颗探索的种子,也藏着对未知世界的渴望与追求。它告诉我们,成长不仅仅…...

Jetson 部署 Faster Whisper
文章目录 WhisperFaster Whisper安装使用尝试WSL部署尝试 Jetson 部署时间戳 实时转录 Whisper Whisper 是一种通用语音识别模型。它是在大量不同音频数据集上进行训练的,也是一个多任务模型,可以执行多语言语音识别、语音翻译和语言识别。 测试&#x…...

测试开发基础——测试分类
四、测试分类 1. 按照测试目标分类 1.1. 界面测试 肉眼看到的任何元素都需要进行测试 界面测试(简称U测试),指按照界面的需求(一般是U设计稿)和界面的设计规则,对我们软件界面所展示的全部内容进行测试…...

【计网】数据链路层:概述之位置|地位|链路|数据链路|帧
✨ Blog’s 主页: 白乐天_ξ( ✿>◡❛) 🌈 个人Motto:他强任他强,清风拂山岗! 💫 欢迎来到我的学习笔记! ① ② ③ ④ ⑤ ⑥ ⑦ ⑧ ⑨ ⑩ 1. 在OSI体系结构中的位置 1. 位置:数…...

【Android】NestedScrollView的简单用法与滚动冲突、滑动冲突
一、NestedScrollView 1. 什么是 NestedScrollView NestedScrollView 是 Android 中一个用于处理垂直方向滚动的布局组件,它继承自 FrameLayout,同时支持嵌套滑动(Nested Scrolling)机制。相比于传统的 ScrollView,N…...

【LeetCode】每日一题 2024_9_13 预算内的最多机器人数目(滑动窗口、单调队列)
LeetCode 启动! 每日一题的题解重新开始连载! 题目:预算内的最多机器人数目 题目链接:2398. 预算内的最多机器人数目 题目描述 代码与解题思路 func maximumRobots(chargeTimes []int, runningCosts []int, budget int64) (an…...

TypeScript中 any和unknown 的区别
1、给其他变量赋值 any可以给其他类型的变量重新赋值; 但unknown是不行的,unknown 可以保持类型安全,从而减少潜在的错误; 2、使用类型上的方法 any可以用类型上的方法,unknown是不可以的...

道可云人工智能元宇宙每日资讯|第五届深圳国际人工智能展(GAIE)在深圳会展中心举行
道可云元宇宙每日简报(2024年9月12日)讯,今日元宇宙新鲜事有: 成都:最高1000万元,研发川藏线数字文旅元宇宙空间 近日,成都市科学技术局启动2025年成都市第一批科技项目和第一批“常年申报”市…...

Bootstrap布局实例(偏移列)
偏移是一个用于更专业的布局的有用功能。它们可用来给列腾出更多的空间。例如,.col-xs-* 类不支持偏移,但是它们可以简单地通过使用一个空的单元格来实现该效果。 为了在大屏幕显示器上使用偏移,请使用 .col-md-offset-* 类。这些类会把一个…...

IP网络广播服务平台任意文件上传漏洞
文章目录 免责声明搜索语法漏洞描述漏洞复现修复建议 免责声明 本文章仅供学习与交流,请勿用于非法用途,均由使用者本人负责,文章作者不为此承担任何责任 搜索语法 icon_hash"-568806419"漏洞描述 该系统在upload接口处可上传任…...

详细阐述Activity的生命周期
目录 1. onCreate(): 2. onStart(): 3. onResume(): 4. onPause(): 5. onStop(): 6. onRestart(): 7. onDestroy(): 活动生命周期图: 特别说明: 例子ÿ…...

spring boot+vue3学习之旅
前言 使用的是黑马程序员的教程,所有资料都来自于它的公众号,侵权即删,这里只做记录学习,然后我还遇到一个问题,不知道为啥idea每次打开一个新项目,maven路径就要重装,很麻烦。 新建项目 之…...