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

C++类与对象(三)

目录

1.再谈构造函数

1.1 构造函数体赋值

1.2 初始化列表

1.3 explicit关键字

2.STATIC成员

2.1 概念

2.2 特性

3.C++中成员初始化的新玩法

4.友元

4.1 友元函数

4.2 友元类

5.内部类

6.再次理解封装

7.再次理解面向对象


本次内容大纲:

1.再谈构造函数

1.1 构造函数体赋值

在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。

class Date{public://构造函数Date(int year, int month, int day){_year = year;_month = month;_day = day;}private:int _year;int _month;int _day;};

虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量的初始化, 构造函数体中的语句只能将其称为赋初值,而不能称作初始化。因为初始化只能初始化一次,而构造函数体内可以多次赋值

class Date{public://构造函数Date(int year, int month, int day){_year = year;  //第一次赋值_year = 2024;  //第二次赋值//.....多次赋值_month = month;_day = day;}private:int _year;int _month;int _day;};

在函数体中,我们可以多次给成员对象赋值,而不是初始化

1.2 初始化列表

初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式

class Date
{
public:Date(int year, int month, int day)//初始化列表:_year(year),_month(month),_day(day){}
private:int _year;int _month;int _day;
};int main()
{Date d1(2024, 9, 15);return 0;
}

注意:

1. 每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)

2. 类中包含以下成员,必须放在初始化列表位置进行初始化:

  • 引用成员变量
  • const成员变量
  • 自定义类型成员(且该类没有默认构造函数时)

引用成员变量和const成员变量都要一个相同的特点,在定义时必须初始化,所以它们只能使用初始化列表初始化

引用创建时必须初始化

int& a; //errorint b = 10;
int& a = b;  //创建就初始化

const变量创建时必须初始化

const int a; //error  创建时未初始化const int a = 10; //创建时初始化

自定义成员:

若类中没有默认构造函数,我们实例化该类对象时应该传参对其初始化,即:初始化没有默认构造函数的类对象时,必须使用初始化列表来对其进行初始化

在这里说明一下,默认构造函数是指不用传参就可以调用的构造函数:

1.我们不写构造函数,编译器自己生成的

2.无参的构造函数

3.全缺省的构造函数

typedef int DateType;
class Stack
{
public://构造函数Stack(int capacity){_a = (DataType*)malloc(sizeof(DataType) * capacity);if(nullptr == _a){perror("Stack::malloc");exit(-1);}_top = 0;_capacity = capacity;}//析构函数~Stack(){if (_a){free(_a);_a = nullptr;_top = _capacity = 0;}}
private:int* _a;int _top;int _capacity;
};class A
{
public:A(int& ref, int a):_ref(ref),_a(a),_st(10){}
private:int& _ref;    //引用const int _a = 2; //constStack _st;    //没有默认构造函数
};int main()
{int p = 10;A a(p, 20);return 0;
}

在定义时就得初始化得变量类型,就必须放在初始化列表进行初始化

还有一个要注意得是,可以看到在构造函数的参数中其中ref引用的意义是防止野引用

如果这里是int ref的话,将一个局部变量给_ref初始化,就会导致_ref引用到一个被释放的空间

在类中声明时给值const int _a = 2;,这个意思是给初始化列表缺省值,如果我们没有在初始化列表对_a进操作,_a就会被赋值为2

3. 尽量使用初始化列表初始化

当你实例化一个对象时,初始化列表就是对象成员定义的地方,无论你是否使用初始化列表,每个对象成员都会走一遍初始化列表(成员变量需要定义出来)

对于内置类型,使用初始化列表和在构造函数体内初始化实际上没有什么区别,其差别就类似以下代码:

//使用初始化列表初始化
int a = 10;//使用函数体初始化(没有使用初始化列表)
int a;
a = 10;

对于自定义类型,使用初始化列表还可以提高代码效率

class Time
{
public:Time(int hour = 1){_hour = hour;}
private:int _hour;
};class test
{
public:test():_t(12)  //调用拷贝构造函数{}
private:Time _t;
};

在类test中,我们调用了一次类Time中的构造函数

在不使用初始化列表的情况下:

class Time
{
public:Time(int hour = 1){_hour = hour;}
private:int _hour;
};class test
{
public:test(int hour){//初始化列表调用了一次构造函数(不使用初始化列表也会走这个流程)Time tmp(hour); //调用一次构造函数_t = tmp;    //调用赋值运算符重载函数}
private:Time _t;
};

与上面那段代码对比,这里多调用一次构造函数和赋值运算符重载函数

初始化野不能解决我们百分之百的初始化问题

例如:

情况一:

typedef int DataType;class Stack
{
public://构造函数Stack(int capacity):_a((DataType*)malloc(sizeof(DataType)* capacity)), _top(0),_capacity(capacity){//我们需要_a做检查,初始化列表完成不了if(nullptr == _a){perror("Stack::malloc");exit(-1);}//我们还需要_a数组初始化一下,初始化初始化列表也完成不了memset(_a, 0, sizeof(int) * _capacity);}//析构函数~Stack(){if (_a){free(_a);_a = nullptr;_top = _capacity = 0;}}
private:DataType* _a;int _top;int _capacity;
};

情况二:

使用构造函数申请一个二维数组

class AA
{
public:AA(int row, int col):_row(row),_col(col){_a = (int**)malloc(sizeof(int*) * row);for (int i = 0; i < col; ++i){_a[i] = (int*)malloc(sizeof(int) * col);}}
private:int** _a;int _row;int _col;
};

初始化列表并不能帮我们完成初始化所有的事情

4. 成员变量在类中声明次序就是其在初始化列表中的初始化顺序与其在初始化列表中的先后次序无关

class A
{
public:A(int a):_a1(a), _a2(_a1){}void Print() {cout << _a1 << " " << _a2 << endl;}
private:int _a2;int _a1;
};//A.输出1  1
//B.程序崩溃
//C.编译不通过
//D.输出1  随机值

测试运行:

答案:D

1.3 explicit关键字

构造函数不仅可以初始化和赋值,对于单个参数的拷贝构造函数,还支持隐式类型转换

class A
{
public:A(int a):_a(a){cout << "A(int a)" << endl;}A(const A& aa):_a(aa._a){cout << "A(const A& aa)" << endl;}
private:int _a;
};int main()
{A a(1);A b = 2;  //隐式类型转换,从内置类型到自定义类型return 0;
}

对于单个参数的拷贝构造函数,编译器是允许这样调用构造函数的,实际上这里还调用了一次拷贝构造函数

在语法上这里一段代码A b = 2;等价于下面两句代码:

A tmp(2); //调用构造函数
A b = tmp; //调用拷贝构造函数

先构造,在拷贝构造

早期的编译器就是这么处理的,当编译器遇到A b = 2;时它会先调用构造函数创建一个临时对象,然后讲这个临时对象拷贝构造给b。但是现在编译器已经做了优化,遇到A b = 2;时会按照A b(2);来进行处理,只会调用一次构造函数,这就是隐式类型转换

在我们仪以前的学习中,其实我们也遇到过隐式类型转换,例如:

int a = 10;
double b = a;

在这个过程中,为了保护a的值不被破环,会产生一个临时变量来存放a的值,然后将这个临时变量赋值给b

从汇编可以看到确实是这样操作的

但是,A b = 2;这种形式的可读性不是很好,所有我们可以使用explicit关键字来修饰构造函数,这样就可以禁止单参数构造函数的隐式类型转换

可以看到加入explicit之后就报错了

2.STATIC成员

2.1 概念

声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用static修饰的 成员函数,称之为静态成员函数。静态成员变量一定要在类外进行初始化

2.2 特性

1. 静态成员为所有类对象所共享,不属于某个具体的对象,存放在静态区

例:

可以看到类中的静态变量不计入类大小,因为它存在于静态区,但是它属于类,属于这个类所有对象的成员

2. 静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明

class A
{
private:static int _a;
};int A::_a = 10;

单独一个类对象成员定义的地方是初始化列表,但是_a是静态成员变量,属于所有A类对象的成员,不是属于某一个对象的,所有它不能使用初始化列表,也不能给初始值,所以它是一个特例,不受访问限定符的影响,在全局域初始化

3. 静态成员函数没有隐藏的this指针,不能访问任何非静态成员

例:

class A
{
public:A(int p):_p(p){cout << "A()" << endl;}static void Print(){cout << _p << _a << endl;}
private:int _p;static int _a;
};int A::_a = 10;int main()
{A a(5);a.Print();return 0;
}

静态成员函数里面不能使用非静态成员

tips:

含有静态成员变量的类,一般含有一个静态成员函数,用于访问静态成员变量

4. 类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问

(1)当静态成员变量公有时,有以下几种访问形式

class A
{
public:int _p;static int _a;
};int A::_a = 10;int main()
{A a;cout << a._a << endl;   //使用类对象突破类域对静态成员进行访问cout << A()._a << endl; //使用匿名结构体突破类域对静态成员进行访问cout << A::_a << endl;  //使用类名突破类域对静态成员进行访问
}

(2)当静态成员变量是私有时,有以下几种访问形式

class A
{
public:int _p;//没有this指针,指定类域和访问限定符就可以访问static int GetACount(){return _a;}
private:static int _a;
};int A::_a = 10;int main()
{A a;cout << a.GetACount() << endl;   //通过对象调用静态成员函数来进行访问cout << A().GetACount() << endl; //通过匿名对象调用静态成员函数来进行访问cout << A::GetACount() << endl;  //通过类名调用静态成员函数进行访问return 0;
}

这里说明一下:

使用非静态成员函数只能 得到_a的值,来使用它的值,并不能访问_a

class A
{
public:int _p;int GetACount(){return _a;}
private:static int _a;
};int A::_a = 10;int main()
{A a;cout << a.GetACount() << endl;   //通过对象调用静态成员函数来得到_a的值return 0;
}

5. 静态成员也是类的成员,受public、protected、private 访问限定符的限制

当静态成员是private时,尽管突破了类域也不能对其进行访问

【问题】

1. 静态成员函数可以调用非静态成员函数吗?

不可以,因为非静态成员函数第一个形参是this指针,而静态成员函数中没有this指针,所以静态函数成员不能调用非静态函数

2. 非静态成员函数可以调用类的静态成员函数吗?

可以,因为在类域中静态成员函数不受类域和访问限定符的限制

使用static情景:

设计一个类,只能在栈上创建对象

class A
{
public:static A GetStackObj(){A N1;return N1;}
private:A(){}
private:int _a;int _b;
};int main()
{A::GetStackObj();return 0;
}

3.C++中成员初始化的新玩法

C++11支持非静态成员变量在声明时进行初始化,但是要注意这里不是初始化,而是给初始化列表一个缺省值

class A
{
public:A(){}private://非静态成员声明时可以给缺省值int* _a = (int*)malloc(sizeof(int) * 10); int _b = 10;static int _c;  //非静态对象不能直接给缺省值
};

初始化列表是你初始化定义的地方,如果你没有给值,那它就会使用你给的缺省值,如果你给了值,那么它就不会使用你的缺省值

我们学习了静态成员变量,现在我们来将他运用到题目中

例:

这是牛客上的一道题目,大家可以思考一下,使用静态变量怎么将这道题目写出来

class sum
{
public:sum(){_ret += _i;++_i;}static int GetACount(){return _ret;}
private:static int _ret;static int _i;
};int sum::_ret = 0;
int sum::_i = 1;class Solution 
{
public:int Sum_Solution(int n) {sum a[n];return sum::_ret;}
};

4.友元

友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度(就是双方之间的亲密度),破坏了封装,所以友元不宜多用。

友元分为:友元函数和友元类

4.1 友元函数

问题:现在尝试去重载operator<<,然后发现没办法将operator重载成成员函数。因为cout的输出流对象和隐含的this指针在抢占第一个参数的位置。this指针默认是第一个参数也就是左操作数了。但是实际使用中cout需要是第一个形参对象,才能正常使用。所以要将operator>>重载成成员函数但又会导致类外没办法访问成员,此时就需要友元来解决。operator>>同理。

我们知道在C++有一件很神奇的事,就是cout和cin可以自动识别输入和输出对象的类型,我们使用它们时不用像C语言一样增加输入输出的格式,这给我们提供了便利,难道C++真有这么神奇吗?其实不是,内置类型的变量可以直接使用cout和cin,是因为它们在库中已经实现了内置类型于运算符的重载

可以查看到,cout在ostream这个类中,而cin在istream这个类中

我们来实现一下自定义运算符的重载,让自定义类型也可以使用<<和>>

这里友元函数就起到作用了

class Date
{friend ostream& operator<<(ostream& _cout, const Date& d);friend istream& operator>> (istream& _cin, Date& d);
public:Date(int year = 1, int month = 1, int day = 1):_year(year),_month(month),_day(day){}private:int _year;int _month;int _day;
};ostream& operator<<(ostream& _cout, const Date& d)
{_cout << d._year << ' ' << d._month << ' ' << d._day;return _cout;
}istream& operator>>(istream& _cin, Date& d)
{_cin >> d._year >> d._month >> d._day;return _cin;
}int main()
{Date d1;cin >> d1;cout << d1;return 0;
}

这里上一节更详细大家有兴趣的可以去看看这里是链接  点击这里

注:

cout是ostream类中的一个全局对象,cin是istream类中的一个全局对象,<<和>>重载具有返回值,是为了连续的实现<<和>>的连续运算,它们的生命周期都是整个工程

说明:

友元函数可访问类的私有和保护成员,但不是类的成员函数

友元函数不能用const修饰

友元函数可以在类定义的任何地方声明,不受类访问限定符限制

一个函数可以是多个类的友元函数

友元函数的调用与普通函数的调用原理相同

4.2 友元类

声明友元类之后,Date中你所有成员函数都是Time中的友元函数,即:Date中的所有成员函数都可以访问Time中的私有成员

//友元类
class Time
{//声明Date是Time的友元类friend class Date;
public:Time(int hour = 1, int minute = 1, int second = 1):_hour(hour),_minute(minute),_second(second){}
private:int _hour;int _minute;int _second;
};class Date
{
public:Date(int year = 1, int month = 1, int day = 1):_year(year),_month(month),_day(day){}//使用Time类void SetTimeOFdate(int hour = 1, int minute = 1, int second = 1){T._hour = hour;T._minute = minute;T._second = second;}private:int _year;int _month;int _day;Time T;
};

友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。

  • 友元关系是单向的,不具有交换性。
  • 比如上述Time类和Date类,在Time类中声明Date类为其友元类,那么可以在Date类中直接访问Time 类的私有成员变量,但想在Time类中访问Date类中私有的成员变量则不行。
  • 友元关系不能传递 如果B是A的友元,C是B的友元,则不能说明C时A的友元。
  • 友元关系不能继承,在继承位置再给大家详细介绍。

5.内部类

概念:如果一个类定义在另一个类的内部,这个内部类就叫做内部类。内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任何优越的访问权限。

注意:内部类就是外部类的友元类,参见友元类的定义,内部类可以通过外部类的对象参数来访问外部类中 的所有成员。但是外部类不是内部类的友元。

特性:

1. 内部类可以定义在外部类的public、protected、private都是可以的。

2. 注意内部类可以直接访问外部类中的static成员,不需要外部类的对象/类名。

3. sizeof(外部类)=外部类,和内部类没有任何关系。

class A 
{
private:static int _a;int _b;//B是A的内部类,B类是A类的天生友元class B{private:void foo(A& a){cout << a._b << endl;cout << _a << endl;}};
};

计算大小为:4

这里A的大小为4,内部类不算做整体的大小

学习了内部类,那么这道题目就可以使用内部类来完成

class Solution {class sum {public:sum() {_ret += _i;++_i;}};public:int Sum_Solution(int n) {sum a[n];return _ret;}static int _ret;static int _i;
};int Solution::_ret = 0;
int Solution::_i = 1;

6.再次理解封装

C++是一门面向对象的语言,面向对象编程语言具有三个特征:封装,继承,多态

C++通过类,将数据的属性和操作数据的方法封装在一起,进行结合就像去旅游一样,去参观一个景点,需要先预约买票,然后排队进入,进去之后只供观赏。若兵马俑可以让人随意的触摸,你一下我一下这些文物能保留多久呢?

所以我们去参观兵马俑时,他只允许我们观赏和拍照,并不允许我们做其他操作,这就是属于封装,通过将景点封装起来提供一个行为供我们使用。防止物品不让其他人破坏

博物馆管理系统

售票系统:负责将票卖给游客

工作人员: 检票,打扫,服务,安保,卫生等

导游:带领客户到指定位置参观博物馆,并且给客户讲解物品的缘由,历史等

通过对比理解,其实C++也是一样,将对象的属性和行为封装在一个类中,通过访问限定符,对类中的内容来进行管理,将用户需要的,我们能提供的设置为:public,为用户提供一个接口,至于其中实现的原理,用户就不需要知道,知道反而会增加使用或者维护的难度

7.再次理解面向对象

其实面向对象就是模拟抽象现实世界

相关文章:

C++类与对象(三)

目录 1.再谈构造函数 1.1 构造函数体赋值 1.2 初始化列表 1.3 explicit关键字 2.STATIC成员 2.1 概念 2.2 特性 3.C中成员初始化的新玩法 4.友元 4.1 友元函数 4.2 友元类 5.内部类 6.再次理解封装 7.再次理解面向对象 本次内容大纲&#xff1a; 1.再谈构造函数 …...

云栖实录 | 阿里云 OpenLake 解决方案重磅发布:多模态数据统一纳管、引擎平权联合计算、数据共享统一读写

新一轮人工智能浪潮正在重塑世界&#xff0c;以生成式 AI 为代表的技术快速应用&#xff0c;推动了数据与智能的深化融合&#xff0c;同时也给数据基础设施带来了全新的变革与挑战。面向 AI 时代的数据基础设施如何构建&#xff1f;底层数据平台架构在 AI 时代如何演进&#xf…...

《线性代数》学渣笔记

文章目录 1 行列式1.1 克拉默法则1.2 基本性质1.3 余子式 M i j M_{ij} Mij​1.4 代数余子式 A i j ( − 1 ) i j ⋅ M i j A_{ij} (-1)^{ij} \cdot M_{ij} Aij​(−1)ij⋅Mij​1.5 具体型行列式计算&#xff08;化为基本型&#xff09;1.5.1 主对角线行列式&#xff1a;主…...

对网页聊天项目进行性能测试, 使用JMeter对于基于WebSocket开发的webChat项目的聊天功能进行测试

登录功能 包括接口的设置和csv文件配置 ​​​​​​ 这里csv文件就是使用xlsx保存数据, 然后在浏览器找个网址转成csv文件 注册功能 这里因为需要每次注册的账号不能相同, 所以用了时间函数来当用户名, 保证尽可能的给正确的注册数据, 时间函数使用方法如下 这里输入分钟, 秒…...

《程序猿之设计模式实战 · 适配器模式》

&#x1f4e2; 大家好&#xff0c;我是 【战神刘玉栋】&#xff0c;有10多年的研发经验&#xff0c;致力于前后端技术栈的知识沉淀和传播。 &#x1f497; &#x1f33b; CSDN入驻不久&#xff0c;希望大家多多支持&#xff0c;后续会继续提升文章质量&#xff0c;绝不滥竽充数…...

Elasticsearch案例

目录 一、创建索引 二、准备数据 三、环境搭建 &#xff08;1&#xff09;环境搭建 &#xff08;2&#xff09;创建实体类 &#xff08;3&#xff09;实现Repository接口 四、实现自动补全功能 五、实现高亮搜索关键字功能 &#xff08;1&#xff09;在repository接口中…...

SpringBoot 项目如何使用 pageHelper 做分页处理 (含两种依赖方式)

分页是常见大型项目都需要的一个功能&#xff0c;PageHelper是一个非常流行的MyBatis分页插件&#xff0c;它支持多数据库分页&#xff0c;无需修改SQL语句即可实现分页功能。 本文在最后展示了两种依赖验证的结果。 文章目录 一、第一种依赖方式二、第二种依赖方式三、创建数…...

GSR关键词排名系统是针对谷歌seo的吗?

是的&#xff0c;GSR关键词排名系统专门针对谷歌SEO&#xff0c;具体通过外部优化手段快速提升关键词排名。不同于传统的SEO策略&#xff0c;GSR系统并不依赖于对网站内容的调整或内部优化&#xff0c;完全通过站外操作实现效果。这意味着&#xff0c;用户不需要花费精力在网站…...

HarmonyOS Next开发----使用XComponent自定义绘制

XComponent组件作为一种绘制组件&#xff0c;通常用于满足用户复杂的自定义绘制需求&#xff0c;其主要有两种类型"surface和component。对于surface类型可以将相关数据传入XComponent单独拥有的NativeWindow来渲染画面。 由于上层UI是采用arkTS开发&#xff0c;那么想要…...

什么是电商云手机?可以用来干什么?

随着电商行业的迅速发展&#xff0c;云手机作为一种创新工具正逐渐进入出海电商领域。专为外贸市场量身定制的出海电商云手机&#xff0c;已经成为许多外贸企业和出海电商卖家的必备。本文将详细介绍电商云手机是什么以及可以用来做什么。 与国内云手机偏向于游戏场景不同&…...

Python 2 和 Python 3的差异

Python 2 和 Python 3 之间有许多差异&#xff0c;Python 3 是 Python 语言的更新版本&#xff0c;目的是解决 Python 2 中的一些设计缺陷&#xff0c;并引入更现代的编程方式。以下是 Python 2 和 Python 3 之间的一些主要区别&#xff1a; 文章目录 1. print 语句2. 整除行为…...

Leetcode 第 139 场双周赛题解

Leetcode 第 139 场双周赛题解 Leetcode 第 139 场双周赛题解题目1&#xff1a;3285. 找到稳定山的下标思路代码复杂度分析 题目2&#xff1a;3286. 穿越网格图的安全路径思路代码复杂度分析 题目3&#xff1a;3287. 求出数组中最大序列值思路代码复杂度分析 题目4&#xff1a;…...

spring 注解 - @NotEmpty - 确保被注解的字段不为空,而且也不是空白(即不是空字符串、不是只包含空格的字符串)

NotEmpty 是 Bean Validation API 提供的注解之一&#xff0c;用于确保被注解的字段不为空。它检查字符串不仅不是 null&#xff0c;而且也不是空白&#xff08;即不是空字符串、不是只包含空格的字符串&#xff09;。 这个注解通常用在 Java 应用程序中&#xff0c;特别是在处…...

深入理解华为仓颉语言的数值类型

解锁Python编程的无限可能&#xff1a;《奇妙的Python》带你漫游代码世界 在编程过程中&#xff0c;数据处理是开发者必须掌握的基本技能之一。无论是开发应用程序还是进行算法设计&#xff0c;了解不同数据类型的特性和用途都至关重要。本文将深入探讨华为仓颉语言中的基本数…...

WPF 的TreeView的TreeViewItem下动态生成TreeViewItem

树形结构仅部分需要动态生成TreeViewItem的可以参考本文。 xaml页面 <TreeView MinWidth"220" ><TreeViewItem Header"功能列表" ItemsSource"{Binding Functions}"><TreeViewItem.ItemTemplate><HierarchicalDataTempla…...

使用Go语言的互斥锁(Mutex)解决并发问题

解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在并发编程中,由于存在竞争条件和数据竞争,我们需要将某些代码片段设定为临界区,并使用互斥锁(Mutex)等同步原语来保护这些临界区。本文将详细介绍Go语言标准库中Mutex的使用方法,以及如何利用它来解决实际…...

Android平台Unity3D下如何同时播放多路RTMP|RTSP流?

技术背景 好多开发者&#xff0c;提到希望在Unity的Android头显终端&#xff0c;播放2路以上RTMP或RTSP流&#xff0c;在设备性能一般的情况下&#xff0c;对Unity下的RTMP|RTSP播放器提出了更高的要求。实际上&#xff0c;我们在前几年发布Unity下直播播放模块的时候&#xf…...

网络:TCP协议-报头字段

个人主页 &#xff1a; 个人主页 个人专栏 &#xff1a; 《数据结构》 《C语言》《C》《Linux》《网络》 文章目录 前言一、TCP协议格式16位源端口号 和 16位目的端口号4位首部长度16位窗口大小32位序号 和 32位确认序号6种标记位 和 16位紧急指针 总结 前言 本文是我对于TCP协…...

JAVA基础:HashMap底层数组容量控制,TreeMap底层存取机制,位运算符,原码反码补码

List常用实现类 List集合常用的实现类有3个 &#xff0c; ArrayList , LinkedList , Vector ArrayList 类似于我们之前的ArrayBox 底层使用数组存储元素&#xff0c; 插入删除的效率低&#xff0c;检索的效率高 当底层数组存储容量不足时&#xff0c;会进行扩容&#xff0c;…...

【Redis】Redis 缓存设计:抗住百万并发量的最佳实践

目录 1. Redis 缓存设计原则1.1 高可用性1.2 数据一致性1.3 读写分离 2. 缓存策略2.1 常用缓存策略2.1.1 缓存穿透2.1.2 缓存雪崩2.1.3 缓存击穿 2.2 额外缓存策略2.2.1 更新策略2.2.2 预热策略2.2.3 侧写缓存 3. Redis 架构设计3.1 单机 vs 集群3.2 Redis 集群示例架构 4. 性能…...

【hot100-java】【缺失的第一个正数】

R9-普通数组篇 class Solution {public int firstMissingPositive(int[] nums) {int nnums.length;for (int i0;i<n;i){while(nums[i]>0&&nums[i]<n&&nums[nums[i]-1]!nums[i]){//交换nums[i]和nums[nums[i]-1]int temp nums[nums[i]-1];nums[nums[i]…...

独立站新手教程转化篇:如何做好移动端优化?

随着移动设备在全球范围内的普及&#xff0c;越来越多消费者选择通过手机或平板电脑&#xff0c;来进行线上购物。因此移动端优化&#xff0c;因此移动端优化&#xff0c;也成为独立站卖家必须重视的一个关键环节。那么独立站移动端需要做好哪些优化工作呢&#xff1f; 选择响…...

Mybatis Plus分页查询返回total为0问题

Mybatis Plus分页查询返回total为0问题 一日&#xff0c;乌云密布&#xff0c;本人看着mybatis plus的官方文档&#xff0c;随手写了个分页查询&#xff0c;如下 Page<Question> questionPage questionService.page(new Page<>(current, size),questionService.g…...

VulnHub-Narak靶机笔记

Narak靶机笔记 概述 Narak是一台Vulnhub的靶机&#xff0c;其中有简单的tftp和webdav的利用&#xff0c;以及motd文件的一些知识 靶机地址&#xff1a; https://pan.baidu.com/s/1PbPrGJQHxsvGYrAN1k1New?pwda7kv 提取码: a7kv 当然你也可以去Vulnhub官网下载 一、nmap扫…...

查看和升级pytorch到指定版本

文章目录 查看和升级pytorch到指定版本查看pytorch的版本python 命令查看pytorch的版本使用pip 命令查看当前安装的PyTorch版本升级PyTorch到指定版本 升级到特定的版本 查看和升级pytorch到指定版本 查看pytorch的版本 python 命令查看pytorch的版本 通过Python的包管理工具…...

Maya---机械模型制作

材质效果&#xff08;4&#xff09;_哔哩哔哩_bilibili 三角面 四边面 多边面 *游戏允许出现三角面和四边面 游戏中一般是低模&#xff08;几千个面&#xff09; 动漫及影视是高模 机械由单独零件组合而成&#xff0c;需独立制作 低面模型到高面模型 卡线是为了将模型保…...

请不要在TS中使用Function类型

在 TypeScript 中&#xff0c;避免使用 Function 作为类型。Function 代表的是“任意类型的函数”&#xff0c;这会带来类型安全问题。对于绝大多数情况&#xff0c;你可能更希望明确地指定函数的参数和返回值类型。 如果你确实想表达一个可以接收任意数量参数并返回任意类型的…...

关于UVM仿真error数量达到指定值就退出仿真的设置

1. 问题描述 在某项目调试过程中&#xff0c;发现通过tc_base.sv中new函数里的set_report_max_quit_count()设置最大error数量不生效&#xff0c;uvm_error数量仍旧是达到10个&#xff08;默认&#xff09;就会退出仿真。 2. 设置uvm_error到达一定数量结束仿真的方式 由白皮…...

chatGPT问答知识合集【二】

Redis 架构说明 Redis 是一个开源的内存数据库&#xff0c;它也可以持久化到磁盘。以下是 Redis 的典型架构说明&#xff1a;### Redis 架构组件&#xff1a;1. **客户端**&#xff1a;与 Redis 服务器进行通信的应用程序或客户端库。2. **Redis 服务器**&#xff1a;执行实际…...

不靠学历,不拼年资,怎么才能月入2W?

之前统计局发布了《2023年城镇单位就业人员年平均工资情况》&#xff0c;2023年全国城镇非私营单位和私营单位就业人员年平均工资分别为120698元和68340元。也就是说在去年非私营单位就业人员平均月薪1W&#xff0c;而私营单位就业人员平均月薪只有5.7K左右。 图源&#xff1a;…...