二、类与对象(三)

17 初始化列表

17.1 初始化列表的引入

之前我们给成员进行初始化时,采用的是下面的这种方式:

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

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

例:

#include <iostream>
using namespace std;
class A
{
public:int _a1;int _a2;//const int _x;//const int _x = 1;
};
int main()
{A aa;return 0;
}

const int _x;前运行结果:

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

const int _x;后运行结果:

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

const int _x = 1;后运行结果:

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

为什么加了const int _x;这条语句后运行起来编译器就报错了呢?这是因为const变量必须在定义的位置初始化,而A aa;是整体定义的地方,并不能在那里对_x进行初始化,虽然我们可以将语句修改为const int _x = 1;,但是这样做的实质并不是初始化,而是给了_x一个缺省值,而且这个特性只有在C++11之后才有,那么在C++11之前该怎么办呢?所以说,必须给每个成员变量找一个定义的位置,不然像const这样的成员将不好处理。

所以为了解决这样的问题,C++引入了初始化列表这样的方式。

17.2 初始化列表的特性

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

例:

class Date
{
public:Date(int year, int month, int day): _year(year), _month(month), _day(day){}
private:int _year;int _month;int _day;
};
  1. 哪个对象调用构造函数,初始化列表就是它所有成员变量定义的位置。不管成员变量是否在初始化列表中显示,编译器都会对每个成员变量进行定义。

例:

#include <iostream>
using namespace std;
class A
{
public:A():_x(1),_a2(1){_a1++;_a2--;}void Print(){cout << _a1 << " " << _a2 << " " << _x << endl;}int _a1 = 2;int _a2 = 2;const int _x;
};
int main()
{A aa;aa.Print();return 0;
}

输出结果:

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

调试结果:

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

从调试结果可以看到,在上述例子中,当初始化列表对_a1进行初始化时,由于_a1未在初始化列表中显式设置,所以使用了缺省值对其进行初始化,而对_a2_x则直接用( )中的值进行初始化。等初始化完成后,初始化列表再去执行{ }中的操作。

  1. 类中包含以下成员,必须放在初始化列表位置进行初始化:
    1. 引用成员变量
    2. const成员变量
    3. 自定义类型成员变量(且该类没有默认构造函数时)

例:

#include <iostream>
using namespace std;
class A
{
public:A(int a)//不是A的默认构造函数:_a(1){}void Print(){cout << _a;}
private:int _a;
};
class B
{
public:B(int a = 1, int ref = 1): _aobj(1), _ref(ref), _n(10){}void Print(){_aobj.Print();cout << " " << _ref << " " << _n << endl;}
private:A _aobj;      // 没有默认构造函数int& _ref;	  // 引用const int _n; // const 
};int main()
{B bb;bb.Print();return 0;
}

初始化列表中无_aobj(1)时运行结果:

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

初始化列表中无_ref(ref)时运行结果:

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

初始化列表中无_n(10)时运行结果:

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

正常运行结果:

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

结论:尽量使用初始化列表初始化,因为不管是否使用初始化列表,对于自定义类型的成员变量,一定会先使用初始化列表进行初始化。

  1. 每个成员变量在初始化列表中只能出现一次,因为只能初始化一次。
  2. 成员变量在类中声明的次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关。

例:

#include <iostream>
using namespace std;
class A
{
public:A(int a):_a1(a), _a2(_a1){}void Print() {cout << _a1 << " " << _a2 << endl;}
private:int _a2;int _a1;
};
int main() 
{A aa(1);//构造函数aa.Print();//
}

输出结果:

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

从输出结果可以看到,由于_a2在类中声明的次序在_a1的前面,所以_a2会比_a1先初始化,而_a2在初始化列表中又是用_a1的值进行初始化,_a1在没有被初始化之前又是随机值,所以_a2初始化所得到的也是随机值。

18 explicit关键字

18.1 explicit关键字的引入

引入explicit关键字之前,我们先来看下面一段代码:

#include <iostream>
using namespace std;
class A
{
public:A(int a):_a1(a){}void Print() {cout << _a1 << " " << _a2 << endl;}
private:int _a2;int _a1;
};
int main() 
{A aa1(1);//构造函数A aa2 = 1;//编译能通过吗?aa1.Print();aa2.Print();return 0;
}

运行结果:

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

从输出结果可以看到,A aa2 = 1;这条语句的左右两边明明不是同一个类型,编译却通过了,这是因为这里发生了隐式的类型转换。

也就是说,A aa2 = 1;这条语句会先生成一个1的具有常性的临时变量,将这个临时变量的类型转换为A后再用来给aa2初始化。

例:

#include <iostream>
using namespace std;
class A
{
public:A(int a):_a1(a){}void Print() const{cout << _a1 << " " << _a2 << endl;}
private:int _a2;int _a1;
};
int main() 
{A aa1(1);//构造函数const A& ref = 10;//类型转换//A& ref = 10;ref.Print();return 0;
}

const修饰A& ref的运行结果:

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

不用const修饰A& ref的运行结果:

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

从输出结果可以看到,由于类型转换时生成的临时变量具有常性,如果被赋值的对象不具有常性的话编译器就会报错。

实际上,构造函数不仅可以构造与初始化对象,对于单个参数或者除第一个参数无默认值其余均有默认值的构造函数,还具有类型转换的作用。

如果不想让这种类型转换发生,就需要引入explicit关键字。

18.2 explicit关键字的特性

  1. 对于单参构造函数,使用explicit修饰后将禁止类型转换。
  2. 对于第一个参数无默认值其余均有默认值的构造函数,使用explicit修饰后也将禁止类型转换。

例:

#include <iostream>
using namespace std;
class Date
{
public:// 1. 单参构造函数,没有使用explicit修饰,具有类型转换作用Date(int year):_year(year){}// 2. 虽然有多个参数,但是创建对象时后两个参数有默认值,使用explicit修饰,禁止类型转换/*explicit Date(int year, int month = 1, int day = 1): _year(year), _month(month), _day(day){}*/Date& operator=(const Date& d){if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;}
private:int _year;int _month;int _day;
};
void Test()
{Date d1(2022);// 用一个整形变量给日期类型对象赋值// 实际编译器背后会用2023构造一个临时对象,而后用临时对象给d1对象进行赋值d1 = 2023;
}
int main()
{Test();return 0;
}

屏蔽单参构造函数后的运行结果:

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

屏蔽多参构造函数后的运行结果:

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

19 static成员

19.1 static成员的引入

引入static成员之前,我们先来看一道面试题。

题目:实现一个类,计算程序中创建出了多少个类对象。

在我们学C语言的时候,可以通过定义一个全局变量count来计数,但到了C++之后,如果还用这样的方式那么类的封装性就无法体现了,所以在C++中引入了static成员来解决这个问题。

C++规定,声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量,用static修饰的成员函数,称之为静态成员函数。

19.2 static成员的特性

  1. 静态成员变量一定要在类外进行定义和初始化,定义时不添加static关键字,在类中只起声明作用。
  2. 静态成员为所有类对象所共享,它不属于某个具体的对象,而是存放在静态区。
  3. 类静态成员的访问方式:
    1. 类名::静态成员
    2. 对象.静态成员
  4. 静态成员函数没有隐藏的this指针,不能访问任何非静态成员
  5. 静态成员也是类的成员,受publicprotectedprivate访问限定符的限制。

掌握了static成员的特性,我们就可以用它来解答刚才的问题了。

#include <iostream>
using namespace std;
class A
{
public:A() { ++_scount; }A(const A& t) { ++_scount; }~A() { --_scount; }int GetACount() { return _scount; }
private:static int _scount;
};
int A::_scount = 0;
int main()
{A a1, a2;A a3(a1);A* ptr = nullptr;cout << a1.GetACount() << endl;cout << a2.GetACount() << endl;cout << ptr->GetACount() << endl;return 0;
}

运行结果:

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

从输出结果可以看到,不仅用对象.静态成员的方式可以访问到静态成员,当对象的指针为空时也可以进行访问。

类名::静态成员这样的访问方式有什么应用场景呢?

我们可以考虑这样一个问题:当我们想知道一个函数内部创建了多少个对象时,该怎么做呢?

由于这个时候对象是在函数内部创建的,那么我们在函数外部再使用对象.静态成员的方式进行访问就明显不合适了,那该怎么办呢?

有人提出了下面这种方法:

#include <iostream>
using namespace std;
class A
{
public:A(int a = 0) { ++_scount; }A(const A& t) { ++_scount; }int GetACount() { return _scount; }
private:static int _scount;
};
int A::_scount = 0;
void Test()
{A a1 = 1, a2 = 1;A a3(a1);
}
int main()
{Test();A a4;cout << a4.GetACount()-1 << endl;return 0;
}

运行结果:

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

从输出结果可以看到,这种方法通过在函数外再创建一个对象,然后用这个对象去访问静态成员之后再减1,就得到了函数内部所创建对象的个数。

这个方法虽然能够达到效果,但是总归是有点撇脚的,有没有什么更好的办法呢?

这个时候就可以考虑用类名::静态成员的方式来进行访问。

采用这种方式的话,我们就需要用staticGetACount函数修饰为静态成员函数,由于静态成员函数没有this指针,所以它就可以通过指定类域来进行调用。

#include <iostream>
using namespace std;
class A
{
public:A(int a = 0) { ++_scount; }A(const A& t) { ++_scount; }static int GetACount() { return _scount; }
private:static int _scount;
};
int A::_scount = 0;
void Test()
{A a1 = 1, a2 = 1;A a3(a1);
}
int main()
{Test();cout << A::GetACount() << endl;return 0;
}

运行结果:

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

19.3 练习

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

这道题本身其实不难,可是题目要求不能使用乘除法、forwhileifelseswitchcase等关键字及条件判断语句(A?B:C),就让问题比较棘手了。

那么在这里,其实我们就可以利用static的特性,通过在一个类里面声明静态成员变量_i_sum,一个用于自增,一个用于求和。而后在类里面定义一个求和函数Sum,让其实现每调用一次_sum就加_i,同时_i自增以实现等差求和。

#include <iostream>
using namespace std;
class Sum
{
public:Sum(){_sum += _i;++_i;}static int GetSum()//用于获取私有成员_sum{return _sum;}
private:static int _i;static int _sum;
};
int Sum::_i = 1;
int Sum::_sum = 0;class Solution
{
public:int Sum_Solution(int n){Sum a[n];return Sum::GetSum();}
};

需要注意的是,由于部分老版的编译器不支持变长数组,所以在编译器上运行时可能会报错,但是在oj上是可以正常通过的。

20 友元

20.1 友元的引入

之前我们想把一个日期类Date输入,是采用这样的方式:

#include <iostream>
using namespace std;
class Date
{
public:Date(int year, int month, int day): _year(year), _month(month), _day(day){}void Print(){cout << _year << "年" << _month << "月" << _day << "日" << endl;}
private:int _year;int _month;int _day;
};
int main()
{Date d1(2023, 10, 5);d1.Print();return 0;
}

运行结果:

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

这样虽然能够实现输出的功能,但每次都要通过对象去调用Print函数才能实现,有没有什么办法能够像内置类型那样直接用cout输出呢?

有人想到如果能将流插入运算符<<重载,那样就好办了,我们不妨来试一下:

#include <iostream>
using namespace std;
class Date
{
public:Date(int year, int month, int day): _year(year), _month(month), _day(day){}ostream& operator<<(ostream& _cout, const Date& d){_cout << d._year << "-" << d._month << "-" << d._day << endl;return _cout;}
private:int _year;int _month;int _day;
};
int main()
{Date d1(2023, 10, 5);cout << d1 << endl;return 0;
}

运行结果:

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

编译器报错了,这是什么原因呢?

实际上,这是因为cout的输出流对象和隐含的this指针在抢占第一个参数的位置,this指针默认是第一个参数也就是左操作数,但是实际使用中cout需要是第一个形参对象,如果要将operator<<重载为成员函数,当前就只能通过下面的方式:

#include <iostream>
using namespace std;
class Date
{
public:Date(int year, int month, int day): _year(year), _month(month), _day(day){}ostream& operator<<(ostream& _cout){_cout << _year << "-" << _month << "-" << _day << endl;return _cout;}
private:int _year;int _month;int _day;
};
int main()
{Date d1(2023, 10, 5);d1 << cout << endl;// d1 << cout; -> d1.operator<<(&d1, cout);return 0;
}

运行结果:

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

虽然这样确实比刚才调用Print函数要方便了,但这明显是不符合常规的调用逻辑的。

要让cout是第一个形参对象,还有个方法就是将operator<<重载成全局函数。

#include <iostream>
using namespace std;
class Date
{
public:Date(int year, int month, int day): _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 << endl;return _cout;
}
int main()
{Date d1(2023, 10, 5);cout << d1 << endl;return 0;
}

运行结果:

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

这个时候好像就能满足我们的要求了,但是新的问题又出现了:类外要访问成员只能将成员变为公有,但这样一来封装性又无法得到保证了。

要解决这个问题,此时就需要友元来解决。

20.2 友元函数的特性

  1. 友元函数是定义在类外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加friend关键字。
  2. 友元函数可访问类的私有和保护成员,但不是类的成员函数。
  3. 友元函数可以在类定义的任何地方声明,不受类访问限定符的限制。
  4. 一个函数可以是多个类的友元函数。
  5. 友元函数的调用与普通函数的调用原理相同。
  6. 当模板函数作为类模板的友元函数时,不能像普通函数那样在类里面友元声明函数名即可,要直接在类模板中定义友元函数

知道了以上友元函数的特性,我们不仅可以用cout来输出自定义类型,还可以用cin来输入自定义类型。

#include <iostream>
using namespace std;
class Date
{friend ostream& operator<<(ostream& _cout, const Date& d);friend istream& operator>>(istream& _cin, Date& d);
public:Date(int year = 1900, 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;_cin >> d._month;_cin >> d._day;return _cin;
}
int main()
{Date d;cin >> d;cout << d << endl;return 0;
}

运行结果:

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

20.3 友元类的特性

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

关于友元类,有以下几点特性:

  1. 友元关系是单向的,不具有交换性。比如上述的Date类,如果我们还想再加一个Time类,并在Time类中声明Date类为其友元类,那么可以在Date类中直接访问Time类的私有成员变量,但想在Time类中访问Date类中私有成员变量则不行。
  2. 友元关系不能传递。也就是说,如果CB的友元,BA的友元,则不能说明CA的友元。
  3. 友元关系不能继承。(该特性会在后续讲到继承的时候再详细介绍)

例:

#include <iostream>
using namespace std;
class Time
{friend class Date;   // 声明日期类为时间类的友元类,则在Date类中就可以直接访问Time类中的私有成员变量friend ostream& operator<<(ostream& _cout, const Date& d);friend istream& operator>>(istream& _cin, Date& d);
public:Time(int hour = 0, int minute = 0, int second = 0): _hour(hour), _minute(minute), _second(second){}private:int _hour;int _minute;int _second;
};
class Date
{friend ostream& operator<<(ostream& _cout, const Date& d);friend istream& operator>>(istream& _cin, Date& d);
public:Date(int year = 1900, int month = 1, int day = 1): _year(year), _month(month), _day(day){}void SetTimeOfDate(int hour, int minute, int second){// 直接访问时间类私有的成员变量_t._hour = hour;_t._minute = minute;_t._second = second;}private:int _year;int _month;int _day;Time _t;
};
ostream& operator<<(ostream& _cout, const Date& d)
{_cout << d._year << "年" << d._month << "月" << d._day << "日"<< d._t._hour << "时" << d._t._minute << "分" << d._t._second << "秒" << endl;return _cout;
}
istream& operator>>(istream& _cin, Date& d)
{_cin >> d._year;_cin >> d._month;_cin >> d._day;_cin >> d._t._hour;_cin >> d._t._minute;_cin >> d._t._second;return _cin;
}
int main()
{Date d1;cin >> d1;cout << d1;
}

运行结果:

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

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

Spring-4-代理

前面提到过&#xff0c;在Spring中有两种类型的代理&#xff1a;使用JDK Proxy类创建的JDK代理以及使用CGLIB Enhancer类创建的基于CGLIB的代理。 你可能想知道这两种代理之间有什么区别&#xff0c;以及为什么 Spring需要两种代理类型。 在本节中&#xff0c;将详细研究代理…

fastadmin想自定义表格的样式,可以使用模板渲染并在模板中调用自定义的方法

fastadmin 如何在模板中使用自定义的方法 比如页面上要对返回的时间&#xff0c;电话&#xff0c;身份证做处理 html页面 <script type"text/html" id"itemtpl"><span id"<%item.id%>" class"margins mobile"><…

播放海康摄像头直播流使用笔记

1、将海康摄像头绑定到萤石云平台&#xff0c;并查看直播流 2、项目中使用 1、安装hls cnpm i hls.js 2、封装组件&#xff08;在components文件夹下新建bodyCapture文件夹下index.vue&#xff09; <template><el-dialogtitle"遗体抓拍"class"bo…

面试题:MySQL 自增主键一定是连续的吗?

文章目录 测试环境&#xff1a;一、自增值的属性特征&#xff1a;1. 自增主键值是存储在哪的&#xff1f;2. 自增主键值的修改机制&#xff1f; 二、新增语句自增主键是如何变化的&#xff1a;三、自增主键值不连续情况&#xff1a;&#xff08;唯一主键冲突&#xff09;四、自…

YBM41567/4A 20V1.0A线性锂电池充电管理芯片

YBM41567/4A 20V1.0A线性锂电池充电管理芯片 概述&#xff1a; YB4156/7/4A是一款狸电池充电管理芯片&#xff0c;集成涓流、恒流、恒压三段式线性充电管理&#xff0c;符合锂电池安全充电规范。充电输入耐压高达24V,充电电流高至1.0A,可通过片外电阻配置。YB4156/7/4A集成防…

【数据结构和算法】独一无二的出现次数

其他系列文章导航 Java基础合集数据结构与算法合集 设计模式合集 多线程合集 分布式合集 ES合集 文章目录 其他系列文章导航 文章目录 前言 一、题目描述 二、题解 2.1 哈希类算法题注意事项 2.2 方法一&#xff1a;判断长度 2.3 方法二&#xff1a; set 判断 2.4 方法…

《手把手教你》系列练习篇之5-python+ selenium自动化测试(详细教程)

1.简介 相信各位小伙伴或者同学们通过前面已经介绍了的PythonSelenium基础篇&#xff0c;通过前面几篇文章的介绍和练习,SeleniumPython的webUI自动化测试算是 一只脚已经迈入这个门槛了要想第二只脚也迈进来。那么就要继续跟随宏哥的脚步继续前行。接下来&#xff0c;宏哥 计…

GLTF编辑器-位移贴图实现破碎的路面

在线工具推荐&#xff1a; 3D数字孪生场景编辑器 - GLTF/GLB材质纹理编辑器 - 3D模型在线转换 - Three.js AI自动纹理开发包 - YOLO 虚幻合成数据生成器 - 三维模型预览图生成器 - 3D模型语义搜索引擎 位移贴图是一种可以用于增加模型细节和形状的贴图。它能够在渲染时针…

C# Winform教程(二):基础窗口程序

1、介绍 winform应用程序是一种智能客户端技术&#xff0c;我们可以使用winform应用程序帮助我们获得信息或者传输信息等。 2、常用属性 Name&#xff1a;在后台要获得前台的控件对象&#xff0c;需要使用Name属性。 Visible&#xff1a;指示一个控件是否可见、 Enable&…

idea 插件开发之 HelloWorld

前言 本文使用的 idea 2023.3 版本进行插件入门开发&#xff0c;首先要说明的是 idea 2023 版本及以后的 idea&#xff0c;对插件开发进行了一定程度的变动&#xff1a; 1、创建项目时不再支持 maven 选项 2、必须是 jdk17 及以后版本&#xff08;点击查看官网版本对应关系&…

【嵌入式开发 Linux 常用命令系列 7.3 -- linux 命令行数值计算】

文章目录 linux 命令行数值计算使用 awk使用 bc 命令使用 Bash 的内置算术扩展使用 expr脚本命令实现 linux 命令行数值计算 在 Linux 命令行中&#xff0c;您可以使用多种方法来执行基本的数学运算。以下是一些示例&#xff1a; 使用 awk awk 是一个强大的文本处理工具&…

【12.28】转行小白历险记-刷算法04

01两两交换链表中的节点 整体思路 1.要修改后一个节点的指向一定要知道前一个节点的指向才可以改变后面一个节点的 2.分情况奇数和偶数节点&#xff0c;终止条件很重要 3.虚拟头节点&#xff0c;是对我们操作的指针是不是头节点进行判断 02删除链表的倒数第N个节点 思路 …

深入理解 C# 中的字符串比较:String.CompareTo vs String.Equals

深入理解 C# 中的字符串比较&#xff1a;String.CompareTo vs String.Equals 在处理字符串时&#xff0c;了解如何正确比较它们对于编写清晰、有效和可靠的 C# 程序至关重要。本文将深入探讨 C# 中的两个常用字符串比较方法&#xff1a;String.CompareTo 和 String.Equals&…

写在2023岁末:敏锐地审视量子计算的当下

本周&#xff0c;《IEEE Spectrum》刊登了一篇出色的文章&#xff0c;对量子计算&#xff08;QC&#xff09;的近期前景进行了深入探讨。 文章的目的并不是要给量子计算的前景泼冷水&#xff0c;而是要说明量子计算的前景还很遥远&#xff0c;并提醒读者量子计算的用例可能很窄…

自定义注解 - java文档生成、结合SpringBoot使用

参考资料&#xff1a; 参考视频 拦截器自定义注解 AOP自定义注解 通过AOP获取属性 拦截器、过滤器、AOP的区别和联系 个人学习笔记及源码 注&#xff1a;这里仅讲怎么使用&#xff0c;具体原理请参考个人学习笔记 自定义注解源码介绍&#xff1a; 其中视频例子2为上述参…

uniapp:全局消息是推送,实现app在线更新,WebSocket,apk上传

全局消息是推送&#xff0c;实现app在线更新&#xff0c;WebSocket 1.在main.js中定义全局的WebSocket2.java后端建立和发送WebSocket3.通知所有用户更新 背景&#xff1a; 开发人员开发后app后打包成.apk文件&#xff0c;上传后通知厂区在线用户更新app。 那么没在线的怎么办&…

如何文件从电脑传到iPhone,这里提供几个方法

本文介绍了如何使用Finder应用程序、iTunes for Windows、iCloud和谷歌照片将照片从Mac或PC传输到iPhone。 如何将照片从Mac传输到iPhone 如果你有一台Mac电脑&#xff0c;里面装满了你想转移到iPhone的照片&#xff0c;这是一件非常简单的事情。只需遵循以下步骤&#xff1a…

参数归一化-实现时间格式化

文章目录 需求分析具体实现完整源码 不知道大家有没有尝试封装过一个时间格式化的函数啊&#xff0c;在之前我封装的时候&#xff0c;开始是觉得手到擒来&#xff0c;但是实践之后发现写非常的shi啊&#xff0c;大量的分支判断&#xff0c;哪怕是映射起到的作用也只是稍微好一点…

第二十一章Java网络通信

网络通信这一章 基本分为三个部分 网络基础概念和TCP,UDP这三个部分主要如下&#xff1a; 计算机网络实现了堕胎计算机间的互联&#xff0c;使得它们彼此之间能够进行数据交流。网络应用程序就是再已连接的不同计算机上运行的程序&#xff0c;这些程序借助于网络协议&#x…

Java线上问题排查思路

1、Java 服务常见问题 Java 服务的线上问题从系统表象来看大致可分成两大类: 系统环境异常、业务服务异常。 系统环境异常&#xff1a;主要从CPU、内存、磁盘、网络四个方面考虑。比如&#xff1a;CPU 占用率过高、CPU 上下文切换频率次数较高、系统可用内存长期处于较低值、…