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指针的地址,这就无法达到预期而错误。

此时,就需要对模板进行特化。即:在原模板类的基础上,针对特殊类型所进行特殊化的实现方

。模板特化中分为函数模板特化类模板特化

函数模板的特化步骤:

  1. 必须要先有一个基础的函数模板

  2. 关键字template后面接一对空的尖括号<>

  3. 函数名后跟一对尖括号,尖括号中指定需要特化的类型

  4. 函数形参表: 必须要和模板函数的基础参数类型完全相同,如果不同编译器可能会报一些奇

怪的错误。

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、继承父类成员访问方式的变化

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

  1. 父类private成员在子类中无论以什么方式继承都是不可见的。这里的不可见是指父类的私有成员还

是被继承到了子类对象中,但是语法上限制子类对象不管在里面还是类外面都不能去访问它。

  1. 父类private成员在子类中是不能被访问,如果父类成员不想在类外直接被访问,但需要在子类中能

访问,就定义为protected。可以看出保护成员限定符是因继承才出现的。

  1. 实际上面的表格我们进行⼀下总结会发现,父类的私有成员在子类都是不可见。父类的其他成员在

子类的访问方式 == Min(成员在父类的访问限定符,继承方式),public > protected > private。

  1. 使用关键字class时默认的继承方式是private,使用struct时默认的继承方式是public,不过最好显

示的写出继承方式。

  1. 在实际运用中⼀般使用都是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、隐藏规则

  1. 在继承体系中父类和子类都有独⽴的作用域。

  2. 子类和父类中有同名成员,子类成员将屏蔽父类对同名成员的直接访问,这种情况叫隐藏。(在子类成员函数中,可以使用父类::父类成员 显示访问)

  3. 需要注意的是如果是成员函数的隐藏,只需要函数名相同就构成隐藏。

  4. 注意在实际中在继承体系里面最好不要定义同名的成员。

// 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、四个常见的默认构造函数

  1. 子类的构造函数必须调用父类的构造函数初始化父类的那⼀部分成员。如果父类没有默认的构造函

数,则必须在子类构造函数的初始化列表阶段显示调用。

  1. 子类的拷贝构造函数必须调用父类的拷贝构造完成父类的拷贝初始化。

  2. 子类的operator=必须要调用父类的operator=完成父类的复制。需要注意的是子类的operator=隐

藏了父类的operator=,所以显示调用父类的operator=,需要指定父类作用域

  1. 子类的析构函数会在被调用完成后⾃动调用父类的析构函数清理父类成员。因为这样才能保证子类

对象先清理子类成员再清理父类成员的顺序。

  1. 子类对象初始化先调用父类构造再调子类构造。

  2. 子类对象析构清理先调用子类析构再调父类的析构。

在这里插入图片描述

在这里插入图片描述

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。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/420731.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

非监督式机器学习:群集

聚类分析是一种非监督式机器学习形式&#xff0c;在此形式下&#xff0c;基于观察值的数据值或特征的相似性&#xff0c;将观察值分组到群集中。 这种就是非监督式机器学习&#xff0c;因为它不使用先前已知的标签值来训练模型。 在聚类分析模型中&#xff0c;标签是群集&#…

帧缓冲 framebuffer

一、基本概念 framebuffer: 帧缓存、帧缓存&#xff08;显示设备&#xff09; Linux内核为显示提供的一套应用程序接口。&#xff08;驱动内核支持&#xff09; 分辨率&#xff1a; 像素点 显示屏&#xff1a;800 * 600&#xff08;横向有800个像素点&#xff0c;纵向有60…

DAY73

作业 pro文件&#xff1a; QT texttospeech 头文件&#xff1a; #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QPushButton> //按钮类 #include <QLabel> //标签类 #include <QLineEdit> //行编译器类 #include…

阿里中间件——diamond

一、前言 最近工作不忙闲来无事&#xff0c;仔细分析了公司整个项目架构&#xff0c;发现用到了很多阿里巴巴集团开源的框架&#xff0c;今天要介绍的是中间件diamond. 二、diamond学习笔记 1、diamond简介 diamond是一个管理持久配置&#xff08;持久配置是指配置数据会持久化…

【Datawhale X 李宏毅苹果书 AI夏令营】《深度学习详解》Task3 打卡

文章目录 前言学习目标一、优化策略二、模型偏差三、优化问题三、过拟合增加训练集给模型一些限制 四、交叉验证五、不匹配总结 前言 本文是【Datawhale X 李宏毅苹果书 AI夏令营】的Task3学习笔记打卡。 学习目标 李宏毅老师对应视频课程&#xff1a;https://www.bilibili.…

QDY421F-16P-25液氨不锈钢液动紧急切断阀

一、产品概述 QDY421F-16P-25液氨不锈钢液动紧急切断阀&#xff0c;采用先进的液动驱动技术&#xff0c;结合高质量的不锈钢材质&#xff0c;专为满足液氨等腐蚀性介质的紧急切断需求而设计。该阀门的工作压力可达16MPa&#xff0c;适用于DN25&#xff08;即25毫米&#xff09;…

系统架构师考试学习笔记第四篇——架构设计实践知识(18)面向服务架构设计理论与实践

本章考点&#xff1a; 第18课时主要学习面向服务架构设计理论与实践。根据考试大纲&#xff0c;本课时知识点会涉及单选题型&#xff08;约占2~5分&#xff09;和案例题&#xff08;25分&#xff09;&#xff0c;本课时内容偏重于方法的掌握和应用&#xff0c;根据以往全国计算…

时序预测|基于小龙虾优化高斯过程GPR数据回归预测Matlab程序COA-GPR 多特征输入单输出 附赠基础GPR

时序预测|基于小龙虾优化高斯过程GPR数据回归预测Matlab程序COA-GPR 多特征输入单输出 附赠基础GPR 文章目录 一、基本原理二、实验结果三、核心代码四、代码获取五、总结 时序预测|基于小龙虾优化高斯过程GPR数据回归预测Matlab程序COA-GPR 多特征输入单输出 附赠基础GPR 一、…

mysql高级sql

文章目录 一&#xff0c;查询1.按关键字排序1.1按关键字排序操作(1)按分数排序查询&#xff08;不加asc默认为升序&#xff09;(2)按分数降序查询&#xff08;DESC&#xff09;(3)使用where进行条件查询(4)使用ORDER BY语句对多个字段排序 1.2使用区间判断查询&#xff08;and/…

如何通过内网穿透实现Pycharm远程服务器编译项目与服务器代码同步

文章目录 前言一、前期准备1. 检查IDE版本是否支持2. 服务器需要开通SSH服务 二、Pycharm本地链接服务器测试1. 配置服务器python解释器 三、使用内网穿透实现异地链接服务器开发1. 服务器安装Cpolar2. 创建远程连接公网地址 四、使用固定TCP地址远程开发 前言 本文主要介绍如…

Unity1 Prefab

修改预设体 进入预设体面板来改 在Hierarchy中可以给预制体添加对象 第一种方法&#xff1a;添加了之后把Hierarchy中的预制体拖到Project中的预制体上 就可以修改原本的预制体 第二种方法&#xff1a;添加了之后在inspector中 点revert 就是重置所有预制体 添加的就没有…

如何远程实时监控员工的电脑屏幕?远程桌面监控的五个可实现方法分享

想象一下&#xff0c;你在办公室喝着咖啡&#xff0c;员工的电脑屏幕却在数百公里之外实时呈现在你的眼前。你可以看到他们在干什么&#xff0c;是埋头工作还是悄悄摸鱼&#xff1f;远程桌面监控让这一切变得触手可及&#xff0c;简直像给了管理者一双“千里眼”&#xff01; 如…

Mysql(二) - 约束, 进阶查询

目录 一.约束 1.not null 2.unique 3.default 4.primary key 5. foreign key 6.check 7. 综合使用 二.进阶查询 1.新增(插入查询的结果) 2.聚合查询 a.聚合函数 b.使用 3.分组查询 4.联合查询 a.内连接 b.外连接 c.自连接 d.子查询 5.合并查询 三.总结 一…

【Unity】简易而又实用的抽卡算法

1.两个数中任选一个&#xff08;抛硬币&#xff09; 基础版本&#xff1a; public int RandomBetweenTwoNumber(int a,int b) {float random Random.Range(0,1f);return radom<0.5f ? a : b ; } 升级版本&#xff08;支持概率调整&#xff09;&#xff1a; /*pa表示“…

微波无源器件 4 基于高阶定向耦合器的双极化波束形成网络

摘要&#xff1a; 一种Ka频段的双极化3dB定向耦合器被设计用于波束形成网络应用。所提出的解决方案对于紧凑Nolen网络。Nolen结构优于器平面和无损特别具有吸引力。两个平行方波导通过口径阵列耦合&#xff0c;设计用于获得两个正交极化之间的所需耦合和高隔离度。 索引词&…

数据结构(7.2_1)——顺序查找

顺序查找&#xff0c;又叫"线性查找"&#xff0c;通常用于线性表&#xff08;或者顺序表和链表&#xff09;。 算法思想&#xff1a;从头到尾全部查找出来&#xff08;或者反过来也OK&#xff09; 顺序查找的实现 typedef struct {//查找表的数据结构(顺序表)Elem…

对接后端download接口报未知异常错误

你一定遇到过这种情况&#xff0c;在一个项目中下载功能明明好好的&#xff0c;下载接口调用方法与前端调用方法封装的好好的&#xff0c;可是换了一个接口&#xff0c;竟然搞罢工了&#xff0c;类似下面这样的&#xff0c;你会不会无从下手&#xff0c;不知道该怎么办呢&#…

MATLAB实现PID参数自动整定

目录 1、项目说明 2、文件说明 1、项目说明 本项目旨在通过 MATLAB 语言实现 PID 参数的自动整定&#xff0c;并设计了一个直观易用的 GUI 界面。该系统特别适用于实验室环境下的 PID 参数自整定任务。整定的核心原则在于优化系统性能&#xff0c;使系统的衰减比尽可能接近理…

深度学习从入门到精通——yolov3算法介绍

YOLO v3 论文地址&#xff1a;https://pjreddie.com/media/files/papers/YOLOv3.pdf论文&#xff1a;YOLOv3: An Incremental Improvement 先验框 (1013)&#xff0c;(1630)&#xff0c;(3323)&#xff0c;(3061)&#xff0c;(6245)&#xff0c;(59 119)&#xff0c; (116 9…

vue页面使用自定义字体

一、准备好字体文件 一般字体问价格式为 .tff&#xff0c;可以去包图网等等网站去下载&#xff0c;好看的太多了&#xff01;&#xff01;&#xff01; 下载下来就是单个的 .tff文件&#xff0c;下载下来后可以进行重命名&#xff0c;但是不要改变他的后缀名&#xff0c;我把他…