C++初阶大总结

news2024/12/23 20:25:02

目录

一.命名空间

1.命名空间定义

2.命名空间使用

二.C++输入&输出

三.缺省参数

四. 函数重载

五.引用

1.常引用

2.传值、传引用效率比较

3.引用和指针的区别

4.引用和指针的不同点:

小知识点:

六.内联函数

七.auto关键字(C++11)

1.auto的使用细则

八.基于范围的for循环(C++11)

1.范围for的使用条件

九.空值nullptr

十.类与对象

1.class与struct

2.类的定义

类的两种定义方式:

1. 声明和定义全部放在类体中

2. 类声明放在.h文件中,成员函数定义放在.cpp文件中

①模版的情况下

​编辑3.成员变量命名规则的建议:

3.类的访问限定符及封装

1 访问限定符

2.访问限定符说明

访问限定符在继承中

3.C++中struct和class的区别是什么

4.封装

4.类的作用域

5.类的实例化

6.类对象模型 

1 如何计算类对象的大小(结构体内存对齐)

7.this指针

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

1.构造函数

内置类型和自定义类型在构造中

小知识点:

2.析构函数

内置类型和自定义类型在析构中

小知识点:析构顺序

析构顺序和次数

3.拷贝构造函数

内置类型和自定义类型在拷贝构造

9.赋值运算符重载

全局的operator==

类内的operator==

内置类型和自定义类型在赋值运算符重载

小知识点:

日期类的实现(已经弄完了) 

10.初始化列表

成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关小知识点:

11.static成员,explicit关键字

小知识点:

​编辑

12this指针

this指针的特性

this在哪里

13.友元函数和友元类(Date里有)

友元类

十一.内存管理

C语言中动态内存管理方式:malloc/calloc/realloc/free

C++内存管理方式

new和delete操作自定义类型

operator new与operator delete函数

new和delete的实现原理

内置类型

自定义类型

定位new表达式(placement-new) (了解)

malloc/free和new/delete的区别

内存泄漏

小知识点new和delete【】匿名对象和重复释放

十二.函数模版和类模版

 函数模板

函数模板概念

函数模板格式

函数模板的实例化

重要例子

类模版

动态顺序表

类模板的实例化

十三.string vector list stack queue priority_queue 反向迭代器

函数模板特化

类模板特化

全特化

偏特化

模板的分离编译

模板总结

知识点总结(易遗漏):

c_str

仿函数


一.命名空间

在C/C++中,变量、函数和后面要学到的类都是大量存在的,这些变量、函数和类的名称将都存 在于全局作用域中,可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化, 以避免命名冲突或名字污染,namespace关键字的出现就是针对这种问题的,比如后面vestor和list等等的模拟实现。

1.命名空间定义

定义命名空间,需要使用到namespace关键字,后面跟命名空间的名字,然后接一对{ }即可,{ }中即为命名空间的成员。

1.命名空间中可以定义变量/函数/类型,

2.命名空间可以嵌套,

3.同一个工程中允许存在多个相同名称的命名空间,编译器最后会合成同一个命名空间中。一个工程中的test.h和上面test.cpp中两个N1会被合并成一个,代码例子

test.cpp

namespace N1

{
 int a;
 int b;
 int Add(int left, int right)
 {
     return left + right;
 }
 namespace N2

 {
     int c;
     int d;
     int Sub(int left, int right)
     {
         return left - right;
     }
 }
}
test.h

namespace N1

{
 int Mul(int left, int right)
 {
     return left * right;
 }
}

注意:一个命名空间就定义了一个新的作用域,命名空间中的所有内容都局限于该命名空间中

2.命名空间使用

命名空间的使用有三种方式:

1.加命名空间名称及作用域限定符

int main()
{
    printf("%d\n", N::a);
    return 0;    
}

2.使用using将命名空间中某个成员引入

using N::b;

int main()
{
    printf("%d\n", N::a);
    printf("%d\n", b);
    return 0;    
}

3.使用using namespace 命名空间名称 引入

using namespce N;

int main()
{
    printf("%d\n", N::a);
    printf("%d\n", b);
    Add(10, 20);
    return 0;    
}

二.C++输入&输出

说明:

1. 使用cout标准输出对象(控制台)和cin标准输入对象(键盘)时,必须包含< iostream >头文件以及按命名空间使用方法使用std。

2. cout和cin是全局的流对象,endl是特殊的C++符号,表示换行输出,他们都包含在包含< iostream >头文件中。

3. 是流插入运算符,>>是流提取运算符。

4. 使用C++输入输出更方便,不需要像printf/scanf输入输出时那样,需要手动控制格式。

C++的输入输出可以自动识别变量类型。

5. 实际上cout和cin分别是ostream和istream类型的对象,>>和也涉及运算符重载等知识, 这些知识我们我们后续才会学习,所以我们这里只是简单学习他们的使用。后面我们还有有 一个章节更深入的学习IO流用法及原理。 注意:早期标准库将所有功能在全局域中实现,声明在.h后缀的头文件中,使用时只需包含对应 头文件即可,后来将其实现在std命名空间下,为了和C头文件区分,也为了正确使用命名空间, 规定C++头文件不带.h;旧编译器(vc 6.0)中还支持格式,后续编译器已不支持,因 此推荐使用+std的方式。

#include <iostream>

using namespace std;

三.缺省参数

缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实 参则采用该形参的缺省值,否则使用指定的实参。

代码例子

void Func(int a = 0)
{
 cout<<a<<endl;
}

int main()
{
 Func();     // 没有传参时,使用参数的默认值

 Func(10);   // 传参时,使用指定的实参

 
 return 0;
}

缺省参数分类.全缺省参数.半缺省参数

void Func(int a = 10, int b = 20, int c = 30)

void Func(int a, int b = 10, int c = 20)

注意:

1. 半缺省参数必须从右往左依次来给出,不能间隔着给

2. 缺省参数不能在函数声明和定义中同时出现,代码例子

//a.h  
void Func(int a = 10);    
// a.cpp 
void Func(int a = 20)  {}   
// 注意:如果生命与定义位置同时出现,恰巧两个位置提供的值不同,那编译器就无法确定到底该用那个缺省值。

3. 缺省值必须是常量或者全局变量

4. C语言不支持(编译器不支持)

四. 函数重载

函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这 些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同,常用来处理实现功能类似数据类型 不同的问题。

1、参数类型不同

int Add(int left, int right)
{
 cout << "int Add(int left, int right)" << endl;
 return left + right;
}
double Add(double left, double right)
{
 cout << "double Add(double left, double right)" << endl;
 return left + right;
}

2、参数个数不同

void f()
{
 cout << "f()" << endl;
}

void f(int a)
{
 cout << "f(int a)" << endl;
}

3、参数类型顺序不同 

void f(int a, char b)
{
 cout << "f(int a,char b)" << endl;
}

void f(char b, int a)
{
 cout << "f(char b, int a)" << endl;
}

五.引用

引用不是新定义一个变量,而是给已存在变量取了一个别名,编译器不会为引用变量开辟内存空 间,它和它引用的变量共用同一块内存空间。

类型& 引用变量名(对象名) = 引用实体;

注意:引用类型必须和引用实体是同种类型的

1. 引用在定义时必须初始化

2. 一个变量可以有多个引用

3. 引用一旦引用一个实体,再不能引用其他实体

1.常引用

void TestConstRef()
{
    const int a = 10;
    //int& ra = a;   // 该语句编译时会出错,a为常量

    const int& ra = a;
    // int& b = 10; // 该语句编译时会出错,b为常量

    const int& b = 10;
    double d = 12.34;
    //int& rd = d; // 该语句编译时会出错,类型不同

    const int& rd = d;
}

注意:如果函数返回时,出了函数作用域,如果返回对象还在(还没还给系统),则可以使用 引用返回,如果已经还给系统了,则必须使用传值返回。代码例子

int& Add(int a, int b)
{
    int c = a + b;
    return c;
}
会出错

2.传值、传引用效率比较

以值作为参数或者返回值类型,在传参和返回期间,函数不会直接传递实参或者将变量本身直接返回,而是传递实参或者返回变量的一份临时的拷贝,因此用值作为参数或者返回值类型,效率是非常低下的,尤其是当参数或者返回值类型非常大时,效率就更低。

3.引用和指针的区别

在语法概念上引用就是一个别名,没有独立空间,和其引用实体共用同一块空间。

在底层实现上实际是有空间的,因为引用是按照指针方式来实现的。

4.引用和指针的不同点:

1. 引用概念上定义一个变量的别名,指针存储一个变量地址。

2. 引用在定义时必须初始化,指针没有要求

3. 引用在初始化时引用一个实体后,就不能再引用其他实体,而指针可以在任何时候指向任何 一个同类型实体

4. 没有NULL引用,但有NULL指针

5. 在sizeof中含义不同:引用结果为引用类型的大小,但指针始终是地址空间所占字节个数(32

位平台下占4个字节)

6. 引用自加即引用的实体增加1,指针自加即指针向后偏移一个类型的大小

7. 有多级指针,但是没有多级引用

8. 访问实体方式不同,指针需要显式解引用,引用编译器自己处理

9. 引用比指针使用起来相对更安全

小知识点:

&的指向不可以被改变  引用做返回值可以提高效率,减少拷贝  &做返回值,返回的内容出作用于必须还存在,静态变量就还在,数组类型的也在

六.内联函数

概念:以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调 用建立栈帧的开销,内联函数提升程序运行的效率。

inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同

一般建议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不 是递归、且频繁调用的函数采用inline修饰,否则编译器会忽略inline特性。

inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址 了,链接就会找不到。

宏的优缺点?

优点:

1.增强代码的复用性。

2.提高性能。

缺点:

1.不方便调试宏。(因为预编译阶段进行了替换) 2.导致代码可读性差,可维护性差,容易误用。 3.没有类型安全的检查 。

C++有哪些技术替代宏?

1. 常量定义换用const enum

2. 短小函数定义 换用内联函数

七.auto关键字(C++11)

std::mapstd::string, std::string>::iterator it = m.begin();

等价于

auto iterator it=m.begin()

注意:

使用auto定义变量时必须对其进行初始化,在编译阶段编译器需要根据初始化表达式来推导auto

的实际类型。因此auto并非是一种“类型”的声明,而是一个类型声明时的“占位符”,编译器在编 译期会将auto替换为变量实际的类型。

1.auto的使用细则

1. auto与指针和引用结合起来使用 用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须 加&

2.在同一行定义多个变量 当在同一行声明多个变量时,这些变量必须是相同的类型,否则编译器将会报错,因为编译 器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量。

八.基于范围的for循环(C++11)

对于一个有范围的集合而言,由程序员来说明循环的范围是多余的,有时候还会容易犯错误。因 此C++11中引入了基于范围的for循环。for循环后的括号由冒号“ :”分为两部分:第一部分是范 围内用于迭代的变量,第二部分则表示被迭代的范围。

注意:范围必须明确

int array[] = { 1, 2, 3, 4, 5 };
 for(auto& e : array)加&可以改变值
     e *= 2;
 
 for(auto e : array)
     cout << e << " ";

与普通循环类似,可以用continue来结束本次循环,也可以用break来跳出整个循环。

1.范围for的使用条件

1. for循环迭代的范围必须是确定的 对于数组而言,就是数组中第一个元素和最后一个元素的范围;对于类而言,应该提供

begin和end的方法,begin和end就是for循环迭代的范围。 注意:以下代码就有问题,因为for的范围不确定

void TestFor(int array[])
{
    for(auto& e : array)
        cout<< e <<endl;
}

九.空值nullptr

NULL可能被定义为字面常量0,或者被定义为无类型指针(void*)的常量。

十.类与对象

1.class与struct

C语言结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。

比如: 之前在数据结构初阶中,用C语言方式实现的栈,结构体中只能定义变量;现在以C++方式实现, 会发现struct中也可以定义函数。

class默认私有,struct默认公有

2.类的定义

class className

{
  类体:由成员函数和成员变量组成

 
};   一定要注意后面的分号

class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分 号不能省略。 类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者成员函数。

类的两种定义方式:

1. 声明和定义全部放在类体中

需注意:成员函数如果在类中定义,编译器可能会将其当成内 联函数处理。

2. 类声明放在.h文件中,成员函数定义放在.cpp文件中

注意:成员函数名前需要加类名::

①模版的情况下

3.成员变量命名规则的建议:
// 我们看看这个函数,是不是很僵硬?

class Date

{

public:
 void Init(int year)
 {
 // 这里的year到底是成员变量,还是函数形参?

 year = year;
 }

private:
 int year;
};
 所以一般都建议这样
class Date

{

public:
 void Init(int year)
 {
 _year = year;
 }

private:
 int _year;
};

3.类的访问限定符及封装

1 访问限定符

C++实现封装的方式:用类将对象的属性与方法结合在一块,让对象更加完善,通过访问权限选 择性的将其接口提供给外部的用户使用。

2.访问限定符说明

1. public修饰的成员在类外可以直接被访问

2. protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的) 3. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止

4. 如果后面没有访问限定符,作用域就到 } 即类结束。

5. class的默认访问权限为private,struct为public(因为struct要兼容C)

注意:访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别

访问限定符在继承中

在继承中pricvate和protected是有很大区别的,private是直接不可见,protected也一样不可以访问,但可以继承,private是都不行,基本用不到,常用的只有

3.C++中struct和class的区别是什么

解答:C++需要兼容C语言,所以C++中struct可以当成结构体使用。另外C++中struct还可以用来 定义类。和class定义类是一样的,区别是struct定义的类默认访问权限是public,class定义的类 默认访问权限是private。注意:在继承和模板参数列表位置,struct和class也有区别,继承中struct默认是公有,而private是私有继承

4.封装

面向对象的三大特性:封装、继承、多态。

封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来 和对象进行交互。

封装本质上是一种管理,让用户更方便使用类。

4.类的作用域

类定义了一个新的作用域,类的所有成员都在类的作用域中。在类体外定义成员时,需要使用 ::

作用域操作符指明成员属于哪个类域。

class Person

{

public:
 void PrintPersonInfo();

private:
 char _name[20];
 char _gender[3];
 int  _age;
};

这里需要指定PrintPersonInfo是属于Person这个类域

void Person::PrintPersonInfo()
{
 cout << _name << " "<< _gender << " " << _age << endl;

5.类的实例化

用类类型创建对象的过程,称为类的实例化

1. 类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间来存储它;比如:入学时填写的学生信息表,表格就可以看成是一个 类,来描述具体学生信息。

2. 一个类可以实例化出多个对象,实例化出的对象 占用实际的物理空间,存储类成员变量

Person类是没有空间的,只有Person类实例化出的对象才有具体的年龄,代码例子

int main()
{
 Person._age = 100;  编译失败:error C2059: 语法错误:“.”
 return 0;
}

3. 做个比方。类实例化出对象就像现实中使用建筑设计图建造出房子,类就像是设计图,只设 计出需要什么东西,但是并没有实体的建筑存在,同样类也只是一个设计,实例化出的对象才能实际存储数据,占用物理空间

6.类对象模型 

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

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

相关文章

24暑假算法刷题 | Day23 | LeetCode 39. 组合总和,40. 组合总和 II,131. 分割回文串

目录 39. 组合总和题目描述题解 40. 组合总和 II题目描述题解 131. 分割回文串题目描述题解 39. 组合总和 点此跳转题目链接 题目描述 给你一个 无重复元素 的整数数组 candidates 和一个目标整数 target &#xff0c;找出 candidates 中可以使数字和为目标数 target 的 所有…

Dolphinscheduler 3.2.1bug记录

问题1&#xff1a;分页只展示首页 解决方案&#xff1a; [Bug][API] list paging missing totalpage by Gallardot Pull Request #15619 apache/dolphinscheduler GitHub 问题2:Hive 数据源连接失败 解决方案&#xff1a;修改源码&#xff1a;HiveDataSourceProcessor.cla…

A Survey on Multimodal Large Language Models(from gpt-4o)

目录 A Survey on Multimodal Large Language Models1. INTRODUCTION2. ARCHITECTURE2.1 Modality encoder2.2 Pre-trained LLM2.3 Modality interface 3. TRAINING STRATEGY AND DATA3.1 Pre-training3.1.1 Training Detail3.1.2 Data 3.2 Instruction-tuning3.2.1 Introducti…

Linux下文件编译器-GCC/G++

前言 本文介绍了c/c的编译过程以及gcc/g的时使用 一.c/c翻译的本质&#xff1a;将高级语言翻译成二进制 1&#xff09;程序翻译过程&#xff1a; &#xff08;1&#xff09;预处理&#xff08;头文件展开、宏替换、去注释、条件编译&#xff09;还是C语言代码 ​ …

hash表如何形成,hash函数如何计算,什么是hash冲突 如何解决 ,Golang map的底层原理及扩容机制

散列表 散列表&#xff08;hash表&#xff09;:根据给定的关键字来计算出关键字在表中的地址的数据结构。也就是说&#xff0c;散列表建立了关键字和 存储地址之间的一种直接映射关系。 问题&#xff1a;如何建立映射管血 散列函数:一个把查找表中的关键字映射成该关键字对应…

平移、旋转、缩放和媒体

一、平移 1.1translate&#xff08;&#xff09;函数 做转换工作可以用translate()函数&#xff0c;这个函数可以改变坐标系。通过改变默认的坐标系&#xff0c;我们可以创建不同的转换方式&#xff0c;包括平移、旋转和缩放。 1.2平移位置案例 案例代码如图1 图1 保存运行如…

【大一公共课】C语言+python语言入门对比+思维导图

C 和 Python 入门教程对比 一、引言 C 语言和 Python 语言都是在编程领域中广泛使用的语言&#xff0c;但它们在语法、应用场景和学习难度上有很大的不同。本教程将对 C 和 Python 的入门知识进行对比&#xff0c;帮助您更好地理解和选择适合自己的编程语言。 二、C 语言入门 …

python爬取某财富网

过程&#xff1a; 点击底部的第3页&#xff0c;第5页&#xff0c;网页刷新了&#xff0c;但是顶部的url地址没有变。那么就是 动态加载&#xff0c; 就是 XHR. 直接请求api. 实验代码如下: import requestsheaders {"User-Agent": "Mozilla/5.0 (Windows NT…

LLM大模型:2024工业AI大模型发展分析

一、大模型为工业智能化发展带来新机遇 1.1. 大模型开启人工智能应用新时代 大模型引领人工智能技术创新和应用。 自 1956 年达特茅斯会议&#xff08;Dartmouth Conference&#xff09;提出人工智能的概念以来&#xff0c;人工智能技术经历了多个发展高峰和低谷。在这一长期的…

《深入浅出WPF》学习笔记一.解析WPF程序

《深入浅出WPF》学习笔记一.解析WPF程序 visual studio帮助我们做了那些事情 引用文件 输出文件类型 按照最原始的方式&#xff0c;我们需要手动打开编译器命令行&#xff0c;使用命令引用类库将代码编译成目标文件。 visual studio会根据我们选择的项目模板&#xff0c;自动…

Java学习Day19:基础篇9

包 final 权限修饰符 代码块 静态代码块在Java中是一个重要的特性&#xff0c;它主要用于类的初始化操作&#xff0c;并且随着类的加载而执行&#xff0c;且只执行一次。静态代码块的实践应用广泛&#xff0c;以下是几个主要的应用场景&#xff1a; 1. 初始化静态变量 静态代…

芋道源码yudao-cloud 二开日记(Editor富文本本地图片上传报错问题)

&#xff1a; 于是找到富文本的组件代码Editor.vue&#xff0c;检查一下上传的接口地址和token有没有传&#xff0c;如下图&#xff1a; 都没有问题&#xff0c;但还是报错&#xff0c;所以试试自定义上传的方法&#xff1a; // 导入上传文件的接口 import * as FileApi from …

数字图像处理 --- 二维离散余弦变换(python实战)

二维离散余弦变换(python实战) &#xff08;注&#xff1a;文中所讨论的离散余弦变换都是DCT-II&#xff09; 在上一篇文章中&#xff0c;我详细介绍了一维离散余弦变换的基本原理&#xff0c;并且以可视化的方式展示了一维DCT中用于分析输入信号的一系列基础余弦波。 在这篇文…

【简单图解 最强计网八股】HTTP 和 HTTPS 的区别

HTTP&#xff08;HyperText Transfer Protocol 超文本传输协议&#xff09; HTTPS&#xff08;Hypertext Transfer Protocol Secure&#xff0c;超文本传输安全协议&#xff09; 通过 传输内容加密 和 身份认证 保证了传输过程的安全性 协议传输内容加密身份认证响应效率端口号…

​LLM大模型从入门到精通(7)--企业大模型开发流程​

一、大模型项目开发的两种方式 2023年以来&#xff0c;随着ChatGPT的火爆&#xff0c;使得LLM成为研究和应用的热点&#xff0c;但是市面上大部分LLM都存在一个共同的问题&#xff1a;模型都是基于过去的经验数据进行训练完成&#xff0c;无法获取最新的知识&#xff0c;以及各…

Axure中继器:数据动态展示的强大工具

在Axure RP这一强大的原型设计工具中&#xff0c;中继器&#xff08;Repeater&#xff09;无疑是一颗璀璨的明珠。它以其独特的功能和广泛的应用场景&#xff0c;成为设计师在创建数据密集型原型时的首选。本文将深入探讨Axure中继器的特点、使用方式及其在数据动态展示中的重要…

新手小白如何投放知乎信息流广告推广?

随着越来越多的企业开始寻求更有效的方式来触达目标客户&#xff0c;知乎作为一个集知识分享、社交互动于一体的平台&#xff0c;已经成为众多品牌青睐的广告投放渠道之一。特别是知乎的信息流广告&#xff0c;因其高度融合的内容形式和精准的目标用户定向&#xff0c;成为了品…

ReactHooks(完结)

上期戳here ReactHooks[三] 一.memo 函数1.1 语法格式 二. useMemo2.1 问题引入2.2 语法格式2.3 使用 useMemo 解决刚才的问题 三.useCallback3.1 useMemo和useCallback区别3.2 语法格式 四.useTransition4.1 问题引入4.2 语法格式4.3 使用 isPending 展示加载状态4.4 注意事项…

Python3 | 练气期,捕获错误异常 、自定义异常处理!

[ 知识是人生的灯塔,只有不断学习,才能照亮前行的道路 ] 0x00 前言简述 在我们开始学习 Python 编程语言的时候, 我们经常会遇到各种错误, 比如:语法错误,运行时错误,逻辑错误等等, 这些错误在开发学习中是不可避免的, 但是随着我们学习的深入可以发现 Python 可以很好的处理…

Java 8-函数式接口

目录 一、概述 二、 函数式接口作为方法的参数 三、函数式接口作为方法的返回值 四、 常用的函数式接口 简单总结 简单示例 4.1 Consumer接口 简单案例 自我练习 实际应用场景 多线程处理 4.2 Supplier接口 简单案例 自我练习 实际应用场景 配置管理 4.3 Func…