lesson03:类和对象(中)

1.类的6个默认的成员函数

2.构造函数

3.析构函数

4.拷贝构造函数

1.类的6个默认的成员函数

空类(类中一个成员都没没有)会有成员函数吗?

其实是有的!如果我们在类中什么都不写,编译器会自动生成6个默认成员函数(用户什么都不写,编译器自动生成的函数叫默认成员函数)。

它们分别是:

1.构造函数

2.析构函数

3.拷贝构造函数

4.赋值运算符重载函数

5.取地址操作符重载函数

6.const取地址操作符重载函数

2.构造函数

2.1定义

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
public:
	void Init(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;
	d1.Init(2022, 7, 5);
	d1.Print();
	Date d2;
	d2.Init(2022, 7, 6);
	d2.Print();
	return 0;
}

构造函数是一个特殊的成员函数,是用来给对象的数据成员初始化的。(用处类似于上面的自定义成员函数Init,注意:这个Init不是构造函数!)

2.2特性

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
public:
	// 1.无参构造函数
	Date()
	{}

	// 2.带参构造函数
	Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
};

void TestDate()
{
	Date d1; // 调用无参构造函数
	Date d2(2015, 1, 1); // 调用带参的构造函数
}

int main()
{
	TestDate();
	return 0;
}

构造函数是特殊的成员函数,构造函数虽然叫构造函数,但它不是用来开空间创建对象的,而是用来初始化对象的。

1.构造函数函数名和类名相同

2.构造函数无返回值,也不用在定义时写返回值类型(简单的来说,连void都不要写,返回值类型直接空着)

3.实例化对象时编译器自动调用构造函数。(这一步是一定进行的,实例化对象时一定会调用构造函数),在对象整个生命周期内只能调用一次(在创建对象的时候必须调用一次,所以不能显示调用构造函数)。

4.构造函数可以重载。

5.在自定义函数TestDate中:

5.1因为d1后面什么都没写,所以实例化(创建)对象d1时,编译器将调用无参构造函数或全缺省构造函数,也就是第一个构造函数。

那为什么只能调用这两种呢?

解答:因为没有传递参数,其他种类的构造函数都要传参数啊。

5.2因为d2后面在括号里写了三个参数(不要问为什么这么写,这是规定),这两个参数将传递给构造函数,所以将调用需传递两个参数的构造函数,也就是第二个函数。

那为什么不能调用给其他的构造函数呢?

解答:以无参构造函数为例,也就是第一个构造函数,他没有形参去接受这两个参数。

那么一般的多参构造,以有4个参数的构造函数为例,它也是不可以的,传递的参数不够。

5.3那么所有的多参构造都不可以吗?

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
public:
	// 1.无参构造函数
	Date()
	{}

	// 2.带参构造函数
	Date(int year, int month, int day, int n = 5)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d(1, 2, 3);
	return 0;
}

解答:其实不是的,像上面这样的半缺省构造函数可以只传三个参数,那么它就是可以的。

注意:看第8行和第12行,构造函数函数名前什么都不写,不要写类型

	Date d3();

注意:如果实例化对象时不给构造函数传参,一定不能写小括号。

这个是函数的声明,如果实例化对象这样写,无法和函数声明区分!

	Date d3(1, 2, 3);

但是,像这样给构造函数传参的,是可以写小括号的,函数声明要写明类型,而上面的代码没有写类型,所以这里是可以和函数声明区分开的。

6.如果用户显示定义了构造函数(就是你自己写了构造函数),编译器将不会生成默认构造函数(默认构造也没有形参,属于一种无参构造)。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d3;
	return 0;
}

前面说过,实例化(创建)对象时编译器一定会自动调用构造函数,但是这里我们没有定义构造函数,会不会报错呢?

答案是不会的,Date类中有一个构造函数,它由编译器生成,我们是看不见的。在实例化d3时调用的是这个由编译器生成的构造函数,这个默认生成的构造函数是无参构造函数,不需要传参。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
private:
	int _year;
	int _month;
	int _day;
public:
	Date (int year,int month,int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
};

int main()
{
	Date d3;
	return 0;
}

这段代码是编不过去的,为什么错了呢?编译器不是会生成默认的无参构造函数吗?

解答:要注意,由于我们自己定义了构造函数,编译器就不再生成默认构造函数了!现在只有一个要传三个参数的构造函数,必须传三个参数。 

7.默认构造函数能干什么呢?

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
public:
	void print()
	{
		cout << _year << ' ' << _month << ' ' << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date d3;
	d3.print();
	return 0;
}

在visual studio 2022社区版上,上面的代码运行后,输出的是随机值,所以默认构造函数貌似没有初始化的功能,那么这个默认构造函数有什么用呢?

解答:c++把类型分为了内置类型(编译器自带的,如int,char等)和自定义类型(自己定义的,如类类型,结构体类型等,注意:凡是指针类型都是内置类型,如类指针类型,结构体指针类型也是内置类型),默认构造函数会自动调用自定义类型成员的构造函数

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Time
{
public:
	Time()
	{
		cout << "Time()" << endl;
		_hour = 0;
		_minute = 0;
		_second = 0;
	}
private:
	int _hour;
	int _minute;
	int _second;
};
class Date
{
private:
	// 基本类型(内置类型)
	int _year;
	int _month;
	int _day;
	// 自定义类型
	Time _t;
};
int main()
{
	Date d;
	return 0;
}

这里打印了“Time()”,说明自定义类型成员_t的无参构造函数1确实被调用了。

总结:在实例化(创建)对象时,构造函数对内置类型成员不作处理,对1自定义类型成员调用它的无参构造函数。

补充:由于标准未说明不允许对内置类型作处理,所以有些编译器会对内置类型作处理;但是标准也未说明一定要对内置类型作处理,有些编译器是不会对内置类型作处理的。

8.考虑到函数重载和调用歧义问题,无参构造和全缺省构造的总数最好不要超过1个

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
public:
	Date()
	{
		_year = 1900;
		_month = 1;
		_day = 1;
	}
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
};
// 以下测试函数能通过编译吗?
void Test()
{
	Date d1;
}
int main()
{
	Test();
	return 0;
}

如这里在实例化d1时,因为d1后面什么都没写,所以编译器要调用d1的无参构造函数或全缺省构造函数,由于这样的函数有两个,编译器不知道用哪个,所以这里就报错了。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
public:
	Date()
	{
		_year = 1900;
		_month = 1;
		_day = 1;
	}
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
};
// 以下测试函数能通过编译吗?
void Test()
{
	Date d1(1);
}
int main()
{
	Test();
	return 0;
}

但是如果我们在实例化对象d1时传一个参数,就可以躲过调用歧义,就可以编过去了,但是极度不建议这么写!!!

9.如果实例化(创建)对象时,当中有自定义类型成员,且该成员所对应的类没有无参构造或全缺省构造,编译器会直接报错。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Time
{
public:
	Time(int a)
	{
		cout << "Time()" << endl;
		_hour = 0;
		_minute = 0;
		_second = 0;
	}
private:
	int _hour;
	int _minute;
	int _second;
};
class Date
{
private:
	// 基本类型(内置类型)
	int _year;
	int _month;
	int _day;
	// 自定义类型
	Time _t;
};
int main()
{
	Date d;
	return 0;
}

 但是,自定义类型成员并不是必须是含有无参构造函数或全缺省构造函数的对象,后面会讲到初始化列表,可以解决这个问题。

可能很多小伙伴已经想到办法了,像下面这样写不就行了?

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Time
{
public:
	Time(int a)
	{
		cout << "Time()" << endl;
		_hour = 0;
		_minute = 0;
		_second = 0;
	}
private:
	int _hour;
	int _minute;
	int _second;
};
class Date
{
private:
	// 基本类型(内置类型)
	int _year;
	int _month;
	int _day;
	// 自定义类型
	Time _t(1);
};
int main()
{
	Date d;
	return 0;
}

 要注意啊,Time _t(1);这种写法是定义对象,类的声明中是不能定义数据对象或变量的,不过在类的成员函数的定义中是可以定义对象或变量的。

3析构函数

3.1概念

析构函数与构造函数的功能相反,构造函数不是创建对象的,析构函数也不是销毁对象的,析构函数的作用是完成对象中资源的清理工作,在对象生命周期结束时由函数自动调用

3.2特性

1.析构函数名就是在类名前加上~

2.无参数,无返回值类型(这里和构造一样,连void也不要写)

3.一个类只能有一个析构函数(因为析构函数没有参数,无法实现重载),若未显式定义,编译器会自动生成默认析构函数

4.对象生命周期结束时编译器自动调用析构函数。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
public:
	Date()
	{
		cout << "Date()" << endl;
		_year = 1900;
		_month = 1;
		_day = 1;
	}
	~Date()
	{
		cout << "~Date()" << endl;
		_year = 0;
		_month = 0;
		_day = 0;
	}
private:
	int _year;
	int _month;
	int _day;
};
void test()
{
	Date d;
}
int main()
{
	test();
	return 0;
}

对象d是在test函数中定义的局部变量,出函数后,自动调用析构函数;在这里,主函数并未结束,但已经调用了对象d的析构函数,可见,对象的析构函数不是一定在主函数结束时调用的。

5.默认的析构函数和默认的构造函数类似,对内置类型不做处理,对自定义类型自动调用它的析构函数。

补充:构造函数都会对自定义类型成员调用它的构造函数;析构函数都会对自定义类型成员调用它的析构函数。这样的特性并不是默认构造和默认析构所特有的,自定义的也有。

6.如果类中没有申请资源(如申请空间,打开文件等),析构函数没必要写,直接使用编译器生成的默认析构函数;有资源申请时一定要写,否则会造成内存泄漏等问题。

4.拷贝构造函数

4.1概念

拷贝构造函数时一个特殊的构造函数,主要体现在形参不同,它的作用也是初始化对象,它也拥有构造函数的特性(它也能对自定义类型成员自动调用它的构造)。

4.2特性

1.拷贝构造函数是构造函数的一个重载

2.拷贝构造函数只有一个形参,且一定是本类类型的引用,使用传值传参编译器会报错,因为会引发无穷递归。

3.拷贝构造函数不仅可以用普通构造函数的方式使用,而且可以用初始化普通变量的方式使用(如int型变量,char型变量等),如下图。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
public:
	Date(int year = 1900, int month = 1, int day = 1)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	//Date(const Date d)//错误写法:编译报错,会引发无穷递归
	Date(const Date& d)// 正确写法
	{
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
	void print()
	{
		cout << _year << ' ' << _month << ' ' << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d2(2024, 4, 19);
	//Date d1(d2);与Date d1 = d2;是等价的,一般情况下写第二种,意思更加明确
	//Date d1(d2);
	Date d1 = d2;
	d1.print();
	return 0;
}

注意:

Date d1;
Date d2;
d2 = d1;

向这样分开写用的就不是拷贝构造函数了,而是使用了默认赋值运算符重载函数(后面会讲)。

3.若未显式定义拷贝构造函数,编译器会生成默认的拷贝构造函数

那默认的拷贝构造也和默认的构造一样吗?也是对内置类型不做处理吗?

解答:默认的拷贝构造函数会将参数按内存存储按字节序完成拷贝,这种拷贝叫浅拷贝,也叫值拷贝。顾名思义,就是将数据成员的值拷贝过去。

4.编译器生成的默认拷贝构造已经能完成拷贝了,还要显式实现吗?

解答:看情况,例如以下的就需要。

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class arr
{
private:
	int* a;
public:
	arr()
	{
		a = (int*)malloc(10 * sizeof(int));
	}
};
int main()
{
	arr a1;
	arr a2 = a1;
	return 0;
}

可以看到,对象a1和对象a2中数据成员,也就是指针变量a是一样的,两个指针指向了同一块空间,这不是我们想要的,我们希望的是让编译器再开一块空间的。

有人就要问了,这也拷贝成功了,有什么不妥吗?

解答:这两个对象的指针变量a指向的是同一块空间,它们是共用这块空间的,会相互影响的。

所以这里需要我们显式写拷贝构造函数,手动开空间,完成深拷贝。

5.拷贝构造函数典型调用场景:

场景一:使用已存在对象创建新对象

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
private:
	int _year;
	int _month;
	int _day;
public:
	Date(int year = 0, int month = 0, int day = 0)
	{
		cout << "Date()" << endl;
		_year = year;
		_month = month;
		_day = day;
	}
	Date(const Date& d)
	{
		cout << "Date(const Date& d)" << endl;
		_year = d._day;
		_month = d._month;
		_day = d._day;
	}
};
void test(Date d)
{

}
int main()
{
	Date d;
	Date d1 = d; //使用已存在对象创建新对象
	return 0;
}

场景二:函数传参时传递对象

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
private:
	int _year;
	int _month;
	int _day;
public:
	Date(int year = 0, int month = 0, int day = 0)
	{
		cout << "Date()" << endl;
		_year = year;
		_month = month;
		_day = day;
	}
	Date(const Date& d)
	{
		cout << "Date(const Date& d)" << endl;
		_year = d._day;
		_month = d._month;
		_day = d._day;
	}
};
void test(Date d)
{

}
int main()
{
	Date d;
	test(d); //使用已存在对象创建新对象
	return 0;
}

场景三:函数返回值返回对象

#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Date
{
private:
	int _year;
	int _month;
	int _day;
public:
	Date(int year = 0, int month = 0, int day = 0)
	{
		cout << "Date()" << endl;
		_year = year;
		_month = month;
		_day = day;
	}
	Date(const Date& d)
	{
		cout << "Date(const Date& d)" << endl;
		_year = d._day;
		_month = d._month;
		_day = d._day;
	}
};
Date test(Date d)
{
	return d;//函数返回值返回对象
}
int main()
{
	Date d;
	test(d); //使用已存在对象创建新对象
	return 0;
}

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

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

相关文章

33. BI - Graph Embedding 回顾以及 GCN 算法介绍

本文为 「茶桁的 AI 秘籍 - BI 篇 第 33 篇」 文章目录 回顾 Graph Embedding什么是 GCNGCN 算法 Hi&#xff0c;你好。我是茶桁。 咱们终于进入核心 BI 课程的最后一部分内容了&#xff0c;之前咱们的重心一直都是在特征选取上&#xff0c;如何获得更好的特征是重中之重&…

踏上R语言之旅:解锁数据世界的神秘密码(二)

R语言学习 文章目录 R语言学习1.数据的R语言表示2.多元数据的R语言调用3.多元数据的简单R语言分析 总结 1.数据的R语言表示 数据框&#xff08;data frame) R语言中用函数data.frame()生成数据框&#xff0c;其句法是&#xff1a; data.frame(data1,data2,…)&#xff0c;例如…

FPGA - ZYNQ 基于EMIO的PS和PL交互

前言&#xff1a; Xilinx ZYNQ系列的芯片&#xff0c;GPIO分为 MIO 、EMIO、AXI_GPIO三种方式。 MIO &#xff1a;固定管脚&#xff0c;属于PS端&#xff0c;也就是ARM端。 EMIO &#xff1a;通过PL扩展&#xff0c;使用时需要分配PL(FPGA)管脚&#xff0c;消耗PL端资源。…

C语言读取数据检索存档《C语言程序设计》·第6章·用数组处理批量数据

C数组使用 添加链接描述 C语言读取数据检索存档 1 添加链接描述 2 添加链接描述 3 添加链接描述 4 添加链接描述 5 添加链接描述 6 添加链接描述 7 matlab转C 添加链接描述

Qt 拖放功能详解:理论与实践并举的深度指南

拖放&#xff08;Drag and Drop&#xff09;作为一种直观且高效的用户交互方式&#xff0c;在现代图形用户界面中扮演着重要角色。Qt 框架提供了完善的拖放支持&#xff0c;允许开发者在应用程序中轻松实现这一功能。本篇博文将详细阐述Qt拖放机制的工作原理&#xff0c;结合详…

Spark-机器学习(3)回归学习之线性回归

在之前的文章中&#xff0c;我们了解我们的机器学习&#xff0c;了解我们spark机器学习中的特征提取和我们的tf-idf&#xff0c;word2vec算法。想了解的朋友可以查看这篇文章。同时&#xff0c;希望我的文章能帮助到你&#xff0c;如果觉得我的文章写的不错&#xff0c;请留下你…

OpenCV从入门到精通实战(八)——基于dlib的人脸关键点定位

本文使用Python库dlib和OpenCV来实现面部特征点的检测和标注。 下面是代码的主要步骤和相关的代码片段&#xff1a; 步骤一&#xff1a;导入必要的库和设置参数 首先&#xff0c;代码导入了必要的Python库&#xff0c;并通过argparse设置了输入图像和面部标记预测器的参数。…

全球首份网络空间测绘报告发布(2022年)

美国、俄罗斯网络韧性位居前 2 位&#xff0c;香港、洛杉矶、新德里位列全球安全城市前三甲 日前&#xff0c;第 55 届亚太先进网络学会&#xff08;APAN&#xff09;学术会议在尼泊尔首都加德满都举行&#xff0c;来自中国的网络空间测绘联合研究中心 ( 以下简称联合研究中心 …

SpringCloud系列(8)--将服务提供者Provider注册进Eureka Server

前言&#xff1a;上一章节我们介绍了Eureka服务端的安装与配置&#xff0c;本章节则介绍关于微服务如何入职Eureka Server Eureka架构原理图 1、修改provider-payment8001子模块的pom.xml文件&#xff0c;引入Eureka Clinet的依赖&#xff0c;然后reolad一下&#xff0c;下载依…

第十五届蓝桥杯题解-数字接龙

题意&#xff1a;经过所有格子&#xff0c;并且不能进行交叉&#xff0c;走的下一个格子必须是当前格子值1%k&#xff0c;输出路径最小的那一条&#xff08;有8个方向&#xff0c;一会粘图&#xff09; 思路&#xff1a;按照8个方向设置偏移量进行dfs&#xff0c;第一个到达终…

【Django】调用django的pbkdf2_sha256加密算法测试

基于django搭建的系统中&#xff0c;用到pbkdf2_sha256&#xff08;&#xff08;Password-Based Key Derivation Function 2&#xff09;&#xff09;加密算法&#xff0c;这里做些代码测试、总结。 PBKDF2简介 PBKDF2是一种基于密码的密钥派生函数&#xff0c;用于从用户提供的…

强固型国产化工业电脑,在电子看板行业应用,机器视觉在汽车产线行业应用

电子看板行业应用 智能电子看板的核心是通过实现工厂的全面可视化、自动化管理&#xff0c;最终达到提高效率、降低成本及提高产品质量的目标。电子看板硬件主要有两部分组成&#xff1a;微型工业计算机&#xff0c;显示终端&#xff08;平板电视、LCD&#xff09; 方案需求 …

免费使用ChatGPT 4.0 和 文心一言 4.0

前言 今天给大家分享如何免费使用ChatGPT4.0 和 文心一言 4.0&#xff0c;废话就不多说了&#xff0c;我们直接入正题。 ChatGPT 4.0 先来看看如何免费使用ChatGPT 4.0 进入Coze登录 https://www.coze.com 选择大圣-GPT-4 文心一言 4.0 通过文心智能体平台&#xff0c;就…

ADSP-21479的开发详解五(AD1939 C Block-Based Talkthru 48 or 96 kHz)音频直通

硬件准备 ADSP-21479EVB开发板&#xff1a; 产品链接&#xff1a;https://item.taobao.com/item.htm?id555500952801&spma1z10.5-c.w4002-5192690539.11.151441a3Z16RLU AD-HP530ICE仿真器&#xff1a; 产品链接&#xff1a;https://item.taobao.com/item.htm?id38007…

【leetcode面试经典150题】64. 删除排序链表中的重复元素 II(C++)

【leetcode面试经典150题】专栏系列将为准备暑期实习生以及秋招的同学们提高在面试时的经典面试算法题的思路和想法。本专栏将以一题多解和精简算法思路为主&#xff0c;题解使用C语言。&#xff08;若有使用其他语言的同学也可了解题解思路&#xff0c;本质上语法内容一致&…

4.6 CORS 支持跨域

CORS (Cross-Origin Resource Sharing &#xff09;是由 W3C 制定的一种跨域资源共享技术标准&#xff0c;其目的就是为了解决前端的跨域请求。在 Java EE 开发中&#xff0c;最常见的前端跨域请求解决方案是 JSONP &#xff0c;但JSONP 只支持 GET 请求&#xff0c;这是 个很大…

毅速:一文说清金属3D打印与传统制造的优劣势

在制造业的演进历程中&#xff0c;传统制造与金属3D打印技术分别代表着不同生产方式。二者各具特色&#xff0c;各有优势&#xff0c;但也存在着明显的差异。毅速为您深入剖析这两种制造方式的核心特点&#xff0c;揭示它们在不同应用场景中的优劣&#xff0c;以期为制造业的未…

二维码门楼牌管理应用平台建设:核实与审核的关键作用

文章目录 前言一、二维码门楼牌管理应用平台的建设背景二、核实与审核在二维码门楼牌管理中的应用三、核实与审核的重要性四、优化建议 前言 随着信息技术的快速发展&#xff0c;二维码门楼牌管理应用平台在社区管理中发挥着越来越重要的作用。本文将深入探讨该平台建设过程中…

二维图像的双线性插值

1. 原理 见下图,假设原图为单通道的灰度图,想求图像中某点Q(x,y)的灰度值。 2. 代码实现 #include <iostream> #include <stdio.h> #include <stdint.h> #include <string> #include<opencv2/opencv.hpp> #include<opencv2/core.hpp>…

黑马程序员Linux简单入门学习笔记

Linux介绍 内核提供系统最核心的功能&#xff0c;如: 调度CPU、调度内存、调度文件系统、调度网络通讯、调度等系统级应用程序&#xff0c;可以理解为出厂自带程序&#xff0c;可供用户快速上手操作系统&#xff0c;如:文件管理器、任务管理器、图片查看、音乐播放等 目录结构 …