类和对象(三)

目录

前言

1.再谈构造函数

1.1 初始化列表

1.2 explicit关键字

 2.static成员

2.1 概念

 2.2 特性

3.友元

3.1. 友元函数

3.2 友元类

4.内部类

5.匿名对象

 6.拷贝对象时的一些编译器优化


前言

今天小编给大家介绍的就是类最后的相关内容,希望大家好好学习理解,以加深大家对类的理解。


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.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. 每个成员变量在初始化列表中最多只能出现一次(初始化只能初始化一次)
2. 类中包含以下成员,必须放在初始化列表位置进行初始化:
引用成员变量
const成员变量
对于引用和const修饰的成员必须在定义的时候初始化,所以我们对于该变量是必须放在初始化列表初始化的。
自定义类型成员(且该类没有默认构造函数时)

但对于没有默认构造的自定义类型,我们一定是需要写出(需要在括号后加上非默认构造的参数),因为系统并不知道该如何调用,如果该自定义类型具有自己的默认构造,我们仍然要将其写入初始化列表,我们就需要更据该参数情况进行传参。

这里还有一点就是:我们不写初始化列表,每个成员变量也会自己走初始化列表。

3. 尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,
一定会先使用初始化列表初始化。
在讲解第四点需要注意的要点之前,这里我需要给大家介绍一道题目:
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();
}
A. 输出1  1
B.程序崩溃
C.编译不通过
D.输出1  随机值

对于上面这道题目,可能大家都会选择 A答案,这里我们运行一下看看结果如何:

 我们可以看到输出的是我们的D答案,那为什么该是选择D答案的呢?这就和我们的第四点有关了。

4. 成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关(这里小编建议,以后大家应该尽可能得将声明和初始化的顺序安排成一致)

1.2 explicit关键字

介绍这个关键字之前,小编先给大家介绍一段程序:

class Date
{
public:
	Date(int year)
		:_year(year)
	{
		cout << "Date(int year, int month, int day)" << endl;
	}
	Date(Date& d1)
	{
		cout << "Date(Date& d1)" << endl;
		_year = d1._year;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1=1;
}

这里我们看到主函数,这里我们看到了这里有个语句是Date d1=1,那么这个语句会发生什么过程呢?之前的话如果=后接的是一个对象,那么我们这里就会调用拷贝构造去初始化这个对象,但是我们这里后面接的是一个常数,那么实际上这里会发生一个隐式转换的过程,这里发生隐式转换有个前提的要求是构造函数中对应的形参要和等号接的值保持一致,那么隐式转换这个过程会发生什么呢?

这里首先会调用构造函数,将1这个值构造成一个对象,再调用拷贝构造函数,去对这个对象进行初始化,那么这里是否会发生小编上面所说的这个过程呢,这里我们看一下运行结果

 这里我们发现我们只是调用了构造函数,那为什么没有拷贝构造函数呢?这就和编译器的优化有关,具体的小编在文章末会给大家具体介绍。

那么这里和我们的这个关键字又有什么关系呢?

从上面我们可以知道:

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

而用我们的explicit关键字去修饰构造函数,就会避免改发生类型转换。这里我给大家演示一下:

 2.static成员

2.1 概念

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

这里小编就给大家介绍一道面试题,以便大家更好的理解这个static修饰符,这里的题目要求是:实现一个类,计算程序中创建出了多少个类对象

题目分析:这里我们可以根据每当我们要创建一个对象,要么利用构造函数,要么就是利用拷贝构造函数,而我们销毁一个对象势必就会调用其析构函数,因此我们可以利用一个变量来记录这个变化,但是这个变量不能是局部的,否则当出了局部作用域就会被销毁而无法完全记录这个过程,因此这里势必我们需要利用一个静态变量去记录这个过程,对于静态变量,我们有全局和static这两种,但是对于全局变量我们在程序内的任何地方都可以使用,这就导致了该变量会在其他位置被改变,导致结果不准确的风险,依次这里我们这里使用static修饰类内变量,且该变量是被private修饰的,这就导致我们只可以通过调用类内相关函数才可以去改变其值。那么下面我们直接看代码。

#include<iostream>
using namespace std;
class A
{
public:
	A() { ++_scount; }
	A(const A& t) { ++_scount; }
	~A() { --_scount; }
	static int GetACount() { return _scount; }
private:
	int _a = 1;//(成员变量————属于每个一个类对象,存储在对象里面)
		static int _scount; //(静态成员变量————属于类,属于类每个对象共享,存储在静态区)
};
int A::_scount = 0;
void TestA()
{
	cout << A::GetACount() << endl;
	A a1, a2;
	A a3(a1);
	cout << A::GetACount() << endl;
}
int main()
{
	TestA();
}

这里我们运行一下,查看该值是否正确:

 2.2 特性

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

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

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

4. 静态成员函数没有隐藏的this指针,不能访问任何非静态成员(指定类域和访问限定符就可以访问)

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

这里根据上面我们还需要补充一点的是:非静态可以调用静态函数,但是静态函数不能调用非静态函数,因为非静态函数需要this指针,但是静态函数没有this指针。(仅限于类内)。

这里小编再给大家讲解一道题目,以加深大家对static这个修饰符的理解:

题目要求:设计一个类,在类外面只能在栈上创建对象, 设计一个类,在类外面只能在堆上创建对象

题目分析:首先我们需要想到,我们的构造函数是支持在栈上也支持在堆上创建的,而且我们每次构造一个对象势必会使用到构造函数,因此这里首先我们不能让类外对象直接访问到类内构造函数,而我们创建在不同存储空间对象就需要我们在类内进行处理,而如何让我们的类外去调用到我们处理过的函数呢?通过对象调用显得不太可能,那么这里我们只能通过类::函数名,对该函数进行访问,因此这里我们就需要使用到static修饰我们特殊处理的函数,代码如下:

class A
{
public:
//栈上创建
static A GetStackObj()
{
A aa;
return aa;
}
//堆上创建
static A* GetHeapObj()
{
return new A;
}
private:
A()
{}
private:
int _a1 = 1;
int _a2 = 2;
};
int main()
{
A::GetStackObj();
A::GetHeapObj();
return 0;
}

3.友元

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

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

3.1. 友元函数

在介绍友元函数之前,小编这里要给大家介绍两个操作符重载函数,首先是 . <<流插入运算符,>>流提取运算符,之前为了访问到类内成员变量,我们基本上是将操作符的重载写在类内的,这里我们以日期类为例,看看我们的这两个操作符写在类内重载会发生什么情况:

这里需要和大家提前说明的是我们的cout是存在于ostream类中的,而我们的cin是存在于istream类中的,因为我们的流插入和流提取都是支持连续的,根据操作符的性质该都是从左往右执行的,所以我们执行完后需要返回。

#include<iostream>
using namespace std;
class Date
{
public:
	Date(int year, int month, int day)
		: _year(year)
		, _month(month)
		, _day(day)
	{}
	ostream& operator<<(ostream& out)
	{
		out << _year << "-" << _month << "-" << _day << endl;
		return out;
	}
	istream& operator >>  (istream& in)
	{
		in >> _year >> _month >> _day;
		return in;
	}
	
private:

	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1(2002, 2, 2);
	d1 << cout;
	d1 >> cin;
	d1 << cout;
	return 0;
}

这里我们运行一下:

以上我们可以看到的是我们重载该运算符后,该调用方式和我们的习惯是不一致的,原因是由于这里的对象会被默认成为第一个参数,如果我们按我们平时的习惯去调用,就会出现:

这里我们的解决方式就是将其写全局,但是我们该如何访问到类内私有成员呢?

1.写一个公共函数去获得

这里虽然可以实现,但是过于繁琐,我们不推荐,大家可以自己尝试一下。

2.友元函数

友元函数可以直接访问类的私有成员,它是定义在类外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加friend关键字,这里我们直接看我们的改造过程

#include<iostream>
using namespace std;
class Date
{
	//函数友元
	friend ostream& operator<<(ostream& out, const Date& d);
	friend istream& operator >>  (istream& in, Date& d);
public:
	Date(int year, int month, int day)
		: _year(year)
		, _month(month)
		, _day(day)
	{}
	
	
private:

	int _year;
	int _month;
	int _day;
};
ostream& operator<<(ostream& out,const Date&d)
{
	out << d._year << "-" << d._month << "-" << d._day << endl;
	return out;
}
istream& operator >>  (istream& in,Date&d)
{
	in >> d._year >>d._month >> d._day;
	return in;
}
int main()
{
	Date d1(2002, 2, 2);
	cout << d1;
	cin >> d1;
	cout<< d1;
	return 0;
}

这里我们调用一下,看看其过程:

这里我们还需要给大家说明几个要点:

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

友元函数不能用const修饰

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

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

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

 

3.2 友元类

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

这里就给大家简单的实现一下类的友元

class Time
{
   friend class Date;   // 声明日期类为时间类的友元类,则在日期类中就直接访问Time类
中的私有成员变量
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
{
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;
};

4.内部类

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

注意:内部类就是外部类的友元类,参见友元类的定义,内部类可以通过外部类的对象参数来访问外部类中的所有成员。但是外部类不是内部类的友元。(内部类在没有创建对象的时候是不占空间的,因为内部类在某个类中只是一个声明)

特性:

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

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

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

4.内部类也受访问限定符限制

#include<iostream>
using namespace std;
class A
{
private:
	static int k;
	int h;
public:
	class B // B天生就是A的友元(内部类可以访问外部类的成员)
	{
	public:
		void foo(const A& a)
		{
			cout << k << endl;//OK
			cout << a.h << endl;//OK
		}
	};
};
int A::k = 1;
int main()
{
	A::B b;
	b.foo(A());

	return 0;
}

5.匿名对象

对于匿名对象的介绍,小编这里就直接在代码中给大家说明一下:

class A
{
public:
A(int a = 0)
:_a(a)
{
cout << "A(int a)" << endl;
}
~A()
{
cout << "~A()" << endl;
}
private:
int _a;
};
class Solution {
public:
int Sum_Solution(int n) {
//...
return n;
}
};
int main()
{
A aa1;
// 不能这么定义对象,因为编译器无法识别下面是一个函数声明,还是对象定义
//A aa1();
// 但是我们可以这么定义匿名对象,匿名对象的特点不用取名字,
// 但是他的生命周期只有这一行,我们可以看到下一行他就会自动调用析构函数
A();//如果匿名对象的构造函数是需要传参的,我们就需要在括号内传参
A aa2(2);
// 匿名对象在这样场景下就很好用,当然还有一些其他使用场景,这个我们以后遇到了再说
Solution().Sum_Solution(10);
return 0;
}

这里大家配合上面的讲解,小编这里在给大家说明归纳这几个要点:

1.首先匿名对象的构造方式是:类名(对应构造函数的参数)

2.匿名对象的生命周期只有一行,这里我们运行一下,这个程序让大家观察一下此过程

 我们可以看到第二次构造函数执行后,后续马上就执行了析构函数,这就说明了该匿名对象的生命周期就只有一行。

3.匿名对象具有常性

这里小编给大家演示一下,这里的类和上面一致,小编只是改了一下主函数的部分内容

int main()
{
	A& b = A();
	return 0;
}

这里我们会发现编译器会给我们报一个这样的错误:

 但是当我们把程序改为:

int main()
{
	const A& b = A();
	return 0;
}

可以发现我们的程序是没有任何错误的:

 4.对于const A& ra=A()此时的const引用会延长匿名对象的生命周期,生命周期就会延长至当前函数的作用域

这里我们写几个变量给大家观察一下:

int main()
{
	A a(1);
	const A& b = A();
	A d(5);
	return 0;
}

调用可以发现:

这里我们第二次调用构造函数并没有马上销毁该匿名对象。

 6.拷贝对象时的一些编译器优化

在传参和传返回值的过程中,一般编译器会做一些优化,减少对象的拷贝,这个在一些场景下还是非常有用的。这里我们直接看代码,看其的具体现象:

class A
{
public:
A(int a = 0)
:_a(a)
{
cout << "A(int a)" << endl;
}
A(const A& aa)
:_a(aa._a)
{
cout << "A(const A& aa)" << endl;
}
A& operator=(const A& aa)
{
cout << "A& operator=(const A& aa)" << endl;
if (this != &aa)
{
_a = aa._a;
}
return *this;
}
~A()
{
cout << "~A()" << endl;
}
private:
int _a;
};
void f1(A aa)
{}
A f2()
{
A aa;
return aa;
}
int main()
{
// 传值传参
A aa1;
f1(aa1);
cout << endl;
// 传值返回
f2();
cout << endl;
// 隐式类型,连续构造+拷贝构造->优化为直接构造
f1(1);
// 一个表达式中,连续构造+拷贝构造->优化为一个构造
f1(A(2));
cout << endl;
// 一个表达式中,连续拷贝构造+拷贝构造->优化一个拷贝构造
A aa2 = f2();
cout << endl;
// 一个表达式中,连续拷贝构造+赋值重载->无法优化
aa1 = f2();
cout << endl;
return 0;
}

这里我们运行一下,看该是否进行了优化

这里很明显就是我们在连续的构造和拷贝构造构造会省略拷贝构造,这也就告诉我们在传参和返回值时最后将会出现构造和拷贝构造的情况写在同一行。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

什么是可信时间戳?可信时间戳电子取证有效吗?

电子数据具有脆弱性、易变性、隐蔽性、载体多样性等特点&#xff0c;容易被复制、删除、篡改且难以被发现。因此&#xff0c;电子数据在实际的司法认定过程中&#xff0c;很难准确鉴定其生成的时间以及内容的真实性、完整性。可信时间戳是一种公认的技术手段&#xff0c;可为电…

精选 100 种最佳 AI 工具大盘点

为了应对对精简流程和数据分析日益增长的需求&#xff0c;整合人工智能工具在多个领域变得至关重要。 本文精选了2023年可用的100种最佳人工智能工具&#xff0c;旨在提高您的生产力、创造力和效率。 以下是 2023 年排名前 100 的人工智能工具&#xff1a; Aidoc&#xff1a;A…

Python获取酷得music并下载,获得无限听

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 环境使用: Python 3.8 Pycharm 模块使用: requests >>> pip install requests re win R 输入cmd 输入安装命令 pip install 模块名 (如果你觉得安装速度比较慢, 你可以切换国内镜像源) 代码实现步骤 <基…

springCloud使用maven

springCloud项目使用maven集成nexus 一&#xff1a;故事背景二&#xff1a;基础概念2.1 什么是Maven2.2 什么是nexus 三&#xff1a;实操3.1 setting文件配置3.2 项目内pom.xml配置3.3 jar上传3.3.1 maven插件上传3.3.2 mvn命令上传3.3.3 页面上传3.3.4 通过Rest的方式进行上传…

麻了,真的不想做测试了...

前言 有不少技术友在测试群里讨论&#xff0c;近期的面试越来越难了&#xff0c;要背的八股文越来越多了,考察得越来越细&#xff0c;越来越底层&#xff0c;明摆着就是想让我们徒手造航母嘛&#xff01;实在是太为难我们这些测试工程师了。 这不&#xff0c;为了帮大家节约时…

今年这情况,大家多一手准备吧......

大家好&#xff0c;最近有不少小伙伴在后台留言&#xff0c;又得准备面试了&#xff0c;不知道从何下手&#xff01; 不论是跳槽涨薪&#xff0c;还是学习提升&#xff01;先给自己定一个小目标&#xff0c;然后再朝着目标去努力就完事儿了&#xff01; 为了帮大家节约时间&a…

Jmeter +Maven+jenkins 接口性能全自动化测试

背景&#xff1a; 首先用jmeter录制或者书写性能测试的脚本&#xff0c;用maven添加相关依赖&#xff0c;把性能测试的代码提交到github&#xff0c;在jenkins配置git下载性能测试的代码&#xff0c;配置运行脚本和测试报告&#xff0c;配置运行失败自动发邮件通知&#xff0c…

桂院校园导航小程序 云开发项目 二次开发教程 1.0.1

Gitee代码仓库&#xff1a;桂院校园导航小程序 GitHub代码仓库&#xff1a;GLU-Guide 先 假装 大伙都成功安装了云开发项目&#xff0c;并能在 微信开发者工具 和 手机 上正确运行。 接着就是 将项目 改成自己的学校。 代码里的注释我就不说明了&#xff0c;有提到 我的学校…

【实践篇】教你玩转JWT认证---从一个优惠券聊起 | 京东云技术团队

引言 最近面试过程中&#xff0c;无意中跟候选人聊到了JWT相关的东西&#xff0c;也就联想到我自己关于JWT落地过的那些项目。 关于JWT&#xff0c;可以说是分布式系统下的一个利器&#xff0c;我在我的很多项目实践中&#xff0c;认证系统的第一选择都是JWT。它的优势会让你…

Java版spring cloud 企业工程项目管理系统平台源码(三控:进度组织、质量安全、预算资金成本、二平台:招采、设计管理)

工程项目管理软件&#xff08;工程项目管理系统&#xff09;对建设工程项目管理组织建设、项目策划决策、规划设计、施工建设到竣工交付、总结评估、运维运营&#xff0c;全过程、全方位的对项目进行综合管理 工程项目各模块及其功能点清单 一、系统管理 1、数据字典&#…

API接口设计方案

API&#xff08;Application Programming Interface&#xff09;接口是一种用于与应用程序进行交互的标准化接口&#xff0c;它允许第三方应用程序通过网络调用应用程序的功能。设计API接口是开发人员在开发软件系统时的重要任务之一&#xff0c;因为API接口的质量和易用性直接…

Docker部署apache superset

使用Docker compose在docker中部署Apache Superset 说明&#xff1a;部署步骤按照superset官网说明总结而来-2023年 1、第一步安装docker 、docker compose。 这里我选择手动下载rpm包&#xff0c;然后yum install *.rpm方式来安装。 下载地址&#xff1a;https://download.…

Dart整理笔记 | Dart参考手册

Dart SDK 安装 如果是使用Flutter 开发&#xff0c;Flutter SDK自带&#xff0c;无需单独安装Dart SDK。 如果需要独立调试运行Dart代码&#xff0c;需要独立安装Dart SDK。 官方文档&#xff1a;https://dart.dev/get-dart windows(推荐): http://www.gekorm.com/dart-wind…

行云流水| CI 3.0 云原生构建全新上线

研发过程中&#xff0c;如何直观且准确地获悉代码提交后的质量状态&#xff1f; 引入持续集成&#xff0c;可以自动化的对代码进行代码检查、单元测试、编译构建、甚至部署与发布&#xff0c;大幅提升开发人员的效率。 腾讯云 CODING 推出 CI 3.0 ——云原生构建&#xff0c;是…

win下C++部署深度学习模型之clion配置pytorch+opencv教程记录

win下clion配置pytorch和OpenCV 一、clion配置vs编译器以及测试二、clion配置pytorch2.1、下载libtorch2. 2、环境变量配置2.3、cmakelist.txt编写2.4、main函数测试运行 三、clion配置opencv3.1、源码下载3.2、编译3.3、环境变量配置3.4、cmakelist.txt编写3.5 main函数测试运…

【密码产品篇】动态口令系统密钥体系结构(SM3、SM4)

【密码产品篇】动态口令系统密钥体系结构&#xff08;SM3、SM4&#xff09; 动态口令是一种一次性口令机制&#xff0c;用户无须记忆口令&#xff0c;也无须手工更改口令。口令通过用户持有的客户端器件生成&#xff0c;并基于一定的算法与服务端形成同步&#xff0c;从而作为…

oracle 学习之 unpivot/pivot函数及hive实现该功能

Oracle中pivot函数详解_实泽有之&#xff0c;无泽虚之的博客-CSDN博客pivot函数格式&#xff1a;pivot(聚合函数 for 需要转为列的字段名 in(需要转为列的字段值))&#xff1b;pivot函数说明&#xff1a;实现将指定字段的值转换为列的效果。https://blog.csdn.net/qq_40018576/…

Win11的两个实用技巧系列之关闭分屏模式方法

怎么关闭Win11电脑分屏模式?Win11关闭分屏模式方法 有用户在使用电脑的时候不小心开启了电脑的分屏模式&#xff0c;导致自己无法正常的进行电脑操作了&#xff0c;本文就为大家带来了Win11关闭分屏模式方法&#xff0c;一起看看吧 Win11电脑分屏模式怎么关闭&#xff1f;有用…

千万不要乱操作了!医院机房这么做真高级

各类中心数据机房广泛分布于银行、库房、交通、电信、医院、教育等行业。系统故障和人为操作不当可能导致各种业务中断或数据丢失&#xff0c;进而影响企业业务的停滞和运行。 医院管理3大难题和挑战 01.缺乏预警、告警机制 医院在使用自动化监控系统之前&#xff0c;主要靠人…

【JVM】1. JVM与Java体系结构

文章目录 1.1. 前言&#x1f349;1.2. 参考书目&#x1f349;1.3. Java及JVM简介&#x1f349;1.4. Java发展的重大事件&#x1f349;1.5. 虚拟机与Java虚拟机&#x1f349;1.6. JVM的整体结构&#x1f349;1.7. Java代码执行流程&#x1f349;1.8. JVM的架构模型&#x1f349;…