【C++】类与对象 第一篇(class,this)

news2024/7/4 4:30:20
 

目录

什么是类?

类的引入

class

类的两种定义方式:

声明与定义分离

类的访问限定符号

访问限定符​编辑

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

封装

类的作用域

类的实例化

类对象模型

如何计算类对象的大小

this指针

C语言和C++实现Stack的对比

C语言实现

C++实现


什么是类?

在C++中,类(Class)是一种用户自定义的数据类型,用于封装数据和方法。它是面向对象程序设计的基本概念之一,通过将相关的数据和方法捆绑在一起,可以更加清晰和灵活地组织代码。

类可以看作是一个模板或者蓝图,用于创建对象(Object)。类定义了对象的属性(成员变量)和行为(成员函数)。成员变量是类的数据成员,用于存储对象的状态;成员函数是类的成员操作,用于操作和访问对象的状态。

通过使用类,能够将数据和操作封装在一起,实现了数据的隐藏和封装,提供了更好的代码重用性和可维护性。同时,类还支持继承机制,允许创建一个类继承另一个类的属性和方法,进一步提高了代码的灵活性和可扩展性。 c语言与c++的区别:

  1. C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。

  2. C++是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。

C语言更像是人们用双手进行洗衣服,不仅需要自己准备洗衣服相关的物品 而C++则是只需人们讲衣服放进洗衣机,洗衣机讲帮你完成这一过程,并且无需关心是如何洗好的

类的引入

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

 //c++兼容C结构体用法
 typedef struct ListNode
 {
     int val;
     struct ListNode* next;
 }LTN;
 ​
 //C的结构体类型是 struct ListNode
 ​
 //C++把结构体升级成了类
 //类是一个整体
 struct Stack
 {
     void Init(int n=4)//缺省参数
     {
         a=(int*)malloc(sizeof(int)*n);
         if(nullptr==a)
         {
             perror("malloc is fail");
             return;
         }
         capacity=n;
         size=0;
     }
 ​
     void Push(int x)
     {
         //...
         a[size++]=x;
     }
 ​
     int* a;
     int size;
     int capacity;
 };
 ​
 int main()
 {
     Stack st;
     st.Init();
     st.Push(1);
     st.Push(2);
     st.Push(3);
 ​
     return 0;
 }

但在C++中一般用class进行类的定义(或C++中更喜欢用class代替)

class

 class className
 {
       // 类体:由成员函数和成员变量组成 
 }; // 一定要注意后面的分号

class定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分号不能省略

类体中内容称为类的成员:类中的变量称为类的属性成员变量; 类中的函数称为类的方法或者 成员函数

 struct Stack
 {
     //成员函数
     void Init(int n=4)
     {
         a=(int*)malloc(sizeof(int)*n);
         if(nullptr==a)
         {
             perror("malloc is fail");
             return;
         }
 ​
         capacity=n;
         size=0;
     }
 ​
     //成员变量  位置任意  
     int* a;
     int size;
     int capacity;
 };

类的两种定义方式:

  1. 声明和定义全部放在类体中需注意:成员函数如果在类中定义,编译器可能会将其当成内 联函数处理

     class Person
     {
     public:
         void Show()
         {
             //...
         }
     ​
     public:
         char* _name;
         char* _sex;
         int _age;
     };

  2. 声明与定义分离
     //Stack.h
     class Stack
     {
         //成员函数
         void Init(int n=4);
         void Push(int x);
     ​
         //成员变量 
         int* a;
         int size;
         int capacity;
     };
     ​
     //Stack.cpp
     #include "Stack.h"
     void Stack::Init(int n)
         {
             a=(int*)malloc(sizeof(int)*n);
             if(nullptr==a)
             {
                 perror("malloc is fail");
                 return;
             }
     ​
             capacity=n;
             size=0;
         }
     void Stack::Push(int x)
     {
       //...
     }
     //注意:缺省值的定义一般是在声明时定义

类的访问限定符号

访问限定符

【访问限定符说明】

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

2.protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)

3. 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止

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

5.class的默认访问权限为private,struct为public(因为struct要兼容C) 注意:访问限定符只在编译时有用,当数据映射到内存后,没有任何访问限定符上的区别

 class Stack
 {
 public:
     //成员函数
     void Init(int n=4);
     void Push(int x);
 ​
 private:
     //成员变量 
     int* a;
     int size;
     int capacity;
 };
注意:成员变量命名时,一般都会在定义变量名字前后➕_ 以防混淆,如:

 class D
 {
 public:
     //成员函数
     void Init(int year,int month,int day)
     {
         _year=year;
         _month=month;
         _year=year;
     }
 ​
 private:
     //成员变量 
     int _year;
     int _month;
     int _day;
 };

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

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

封装

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

封装本质上是一种管理,让用户更方便使用类。比如:对于电脑这样一个复杂的设备,提供给用 户的就只有开关机键、通过键盘输入,显示器,USB插孔等,让用户和计算机进行交互,完成日 常事务。但实际上电脑真正工作的却是CPU、显卡、内存等一些硬件元件。

类的作用域

类定义了一个新的作用域,类的所有成员都在类的作用域中在类体外定义成员时,需要使用 :: 作用域操作符指明成员属于哪个类域。

 class Person
 {
 public:
     void PrintPersonInfo();
 private:
     char _name[20];
     char _gender[3];
     int  _age;
 };
 // 这里需要指定PrintPersonInfo是属于Person这个类域
  void Person::PrintPersonInfo()
 {
     cout << _name << " "<< _gender << " " << _age << endl;
 }

类的实例化

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

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

    类就像谜语一样,对谜底来进行描述,谜底就是谜语的一个实例。

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

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

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

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

定义时才开空间(类对象的实例化)

 
//类-设计图纸
 class Data
 {
 public:
     //成员函数
     void Init(int year,int month,int day)
     {
         _year=year;
         _month=month;
         _year=year;
     }
 ​
 private:
     //声明
     int _year;
     int _month;
     int _day;
 };
 ​
 int main()
 {
     //类对象实例化 -- 开空间
     //实例化 -- 用设计图建造房子
     Data d1;
     Data d2;
 ​
     return 0;
 } 

错误用法:

类对象模型

如何计算类对象的大小

 class Data
 {
 public:
     //成员函数
     void Init(int year,int month,int day)
     {
         _year=year;
         _month=month;
         _year=year;
     }
 ​
     //声明
     int _year;
     int _month;
     int _day;
 };
 ​
 int main()
 {
     Data d1;
     Data d2;
 ​
     d1.Init(2077,2,2); 
     d1._year++;
 ​
     cout<<sizeof(d1)<<endl;//12
 ​
     return 0;
 } 

为什么 d1 是12字节?

成员函数就像是公共设施,在计算大小时只需要将属于自己的进行计算即可 每个对象成员变量是不一样的,需要单独存储,每个对象调用成员函数是一样的,放到共享区域(代码段)

此处计算占有大小也存在内存对齐问题(内存对齐问题具体讲解C语言:自定义类型(结构体,枚举,联合)-CSDN博客)

结构体内存对齐规则

  1. 第一个成员在与结构体偏移量为0的地址处。

  2. 其他成员变量要对齐到某个数字(对齐数)的整数倍的地址处。

    注意:对齐数 = 编译器默认的一个对齐数 与 该成员大小的较小值。

    VS中默认的对齐数为8

  3. 结构体总大小为:最大对齐数(所有变量类型最大者与默认对齐参数取最小)的整数倍。

  4. 如果嵌套了结构体的情况,嵌套的结构体对齐到自己的最大对齐数的整数倍处,结构体的整 体大小就是所有最大对齐数(含嵌套结构体的对齐数)的整数倍。

 
// 类中既有成员变量,又有成员函数 
 class A1 
 {
 public:
     void f1(){}
 private:
     int _a;
 };
 ​
 // 类中仅有成员函数 
 class A2 
 { 
 public:
    void f2() 
    {
    }
 };
 ​
 // 类中什么都没有---空类 
 class A3
 {
 };
 sizeof(A1)=4;
 sizeof(A2)=1;
 sizeof(A3)=1;
 这是为什么呢?

sizeof(A2)=1; sizeof(A3)=1; 这1字节仅仅是用来占位的表示对象存在,被实例化


this指针

这就引入了this,此处this是编译器自动生成的,无需自定义,进行自定义也会报错

当然这样写是正确的,此处写与不写都一样

那this存放在哪里?-- 存放才上,应为它是隐含形参

Date类中有 Init 与 Print 两个成员函数,函数体中没有关于不同对象的区分,那当d1调用 Init 函数时,该函数是如何知道应该设置d1对象,而不是设置d2对象呢? C++中通过引入this指针解决该问题,即:C++编译器给每个“非静态的成员函数“增加了一个隐藏 的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量”的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编 译器自动完成

// 下面程序编译运行结果是? A、编译报错 B、运行崩溃 C、正常运行 
 class Date
 {
 public:
 ​
     void Init(int year,int month,int day)
     {
         cout << this << endl;
 ​
         this->_year = year;
         this->_month = month;
         this->_day = day;
     }
 ​
     void Print()
     {
         cout << this << endl;
         cout << "Print()" << endl;
     } 
 ​
 private:
     int _year;
     int _month;
     int _day;
 };
 ​
 int main() 
 {
     Date* ptr = nullptr;
     ptr->Print();         //正常运行
   //ptr->Init(2077,2,2); //运行崩溃
 ​
     return 0;
 }

ptr->Print(); 正常运行的原因: 调用成员函数要调用成员指针,此时ptr传递给了this,此时this指针本身为空不报错

ptr->Init(2077,2,2); 运行崩溃的原因: 此处调用了this (this->_year = year;)对this进行了解引用

     ptr->Print();//正常运行
     (*ptr).func();//正常运行

正常运行的原因:有没有解引用的行为取决于右边要访问的对象在不在对象里面,而不是有没有用那个符号

C语言和C++实现Stack的对比

C语言实现

 typedef int DataType;
 typedef struct Stack
 {
     DataType *array;
     int capacity;
     int size;
 } Stack;
 void StackInit(Stack *ps)
 {
     assert(ps);
     ps->array = (DataType *)malloc(sizeof(DataType) * 3);
     if (NULL == ps->array)
     {
         assert(0);
         return;
     }
     ps->capacity = 3;
     ps->size = 0;
 }
 void StackDestroy(Stack *ps)
 {
     assert(ps);
     if (ps->array)
     {
         free(ps->array);
         ps->array = NULL;
         ps->capacity = 0;
         ps->size = 0;
     }
 }
 void CheckCapacity(Stack *ps)
 {
     if (ps->size == ps->capacity)
     {
         int newcapacity = ps->capacity * 2;
         DataType *temp = (DataType *)realloc(ps->array, newcapacity * sizeof(DataType));
                                             
         if (temp == NULL)
         {
             perror("realloc申请空间失败!!!");
             return;
         }
         ps->array = temp;
         ps->capacity = newcapacity;
     }
 }
 void StackPush(Stack *ps, DataType data)
 {
     assert(ps);
     CheckCapacity(ps);
     ps->array[ps->size] = data;
     ps->size++;
 }
 int StackEmpty(Stack *ps)
 {
     assert(ps);
     return 0 == ps->size;
 }
 void StackPop(Stack *ps)
 {
     if (StackEmpty(ps))
         return;
     ps->size--;
 }
 DataType StackTop(Stack *ps)
 {
     assert(!StackEmpty(ps));
     return ps->array[ps->size - 1];
 }
 int StackSize(Stack *ps)
 {
     assert(ps);
     return ps->size;
 }
 int main()
 {
     Stack s;
     StackInit(&s);
     StackPush(&s, 1);
     StackPush(&s, 2);
     StackPush(&s, 3);
     StackPush(&s, 4);
     printf("%d\n", StackTop(&s));
     printf("%d\n", StackSize(&s));
     StackPop(&s);
     StackPop(&s);
     printf("%d\n", StackTop(&s));
     printf("%d\n", StackSize(&s));
     StackDestroy(&s);
     return 0;
 }

可以看到,在用C语言实现时,Stack相关操作函数有以下共性: 每个函数的第一个参数都是Stack* 函数中必须要对第一个参数检测,因为该参数可能会为NULL 函数中都是通过Stack*参数操作栈的 调用时必须传递Stack结构体变量的地址

结构体中只能定义存放数据的结构,操作数据的方法不能放在结构体中,即数据和操作数据 的方式是分离开的,而且实现上相当复杂一点,涉及到大量指针操作,稍不注意可能就会出错。

C++实现

 typedef int DataType;
 class Stack
 {
 public:
     void Init()
     {
         _array = (DataType *)malloc(sizeof(DataType) * 3);
         if (NULL == _array)
         {
             perror("malloc申请空间失败!!!");
             return;
         }
         _capacity = 3;
         _size = 0;
     }
     void Push(DataType data)
     {
         CheckCapacity();
         _array[_size] = data;
         _size++;
     }
     void Pop()
     {
         if (Empty())
             return;
         _size--;
     }
     DataType Top()
     {
         return _array[_size - 1];
     }
     int Empty()
     {
         return 0 == _size;
     }
     int Size()
     {
         return _size;
     }
     void Destroy()
     {
         if (_array)
         {
             free(_array);
             _array = NULL;
             _capacity = 0;
             _size = 0;
         }
     }
 ​
 private:
     void CheckCapacity()
     {
         if (_size == _capacity)
         {
             int newcapacity = _capacity * 2;
             DataType *temp = (DataType *)realloc(_array, newcapacity *sizeof(DataType));
                                                  
             if (temp == NULL)
             {
                 perror("realloc申请空间失败!!!");
                 return;
             }
             _array = temp;
             _capacity = newcapacity;
         }
     }
 ​
 private:
     DataType *_array;
     int _capacity;
     int _size;
 };
 int main()
 {
     Stack s;
     
     s.Init();
     s.Push(1);
     s.Push(2);
     s.Push(3);
     s.Push(4);
     printf("%d\n", s.Top());
     printf("%d\n", s.Size());
     s.Pop();
     s.Pop();
     printf("%d\n", s.Top());
     printf("%d\n", s.Size());
     s.Destroy();
     return 0;
 }

C++中通过类可以将数据 以及 操作数据的方法进行完美结合,通过访问权限可以控制那些方法在 类外可以被调用,即封装,在使用时就像使用自己的成员一样,更符合人类对一件事物的认知。 而且每个方法不需要传递Stack的参数了,编译器编译之后该参数会自动还原,即C++中Stack 参数是编译器维护的,C语言中需用用户自己维护

c:

        1.数据都是分离的

        2.数据访问控制是自由的,不受限制

c++:

        1.数据和方法都封装到类里面

        2.控制访问方式,给你访问公有,不能访问私有

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

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

相关文章

程序员新手村常见问题

到今年已经工作十一个年头了&#xff0c;把这些年自己出现在自己身上或者同事身上的问题记录下来。 手里有锤子&#xff0c;看神马都是钉子 新人程序员很容易手段目的化&#xff0c;战术战略化。学了一门新技术后&#xff0c;不管具体的技术场景&#xff0c;哪里都想拿出来比…

2023年【广东省安全员A证第四批(主要负责人)】考试题及广东省安全员A证第四批(主要负责人)考试内容

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 广东省安全员A证第四批&#xff08;主要负责人&#xff09;考试题是安全生产模拟考试一点通总题库中生成的一套广东省安全员A证第四批&#xff08;主要负责人&#xff09;考试内容&#xff0c;安全生产模拟考试一点通…

CNN 网络结构简介

本文通过整理李宏毅老师的机器学习教程的内容&#xff0c;介绍 CNN&#xff08;卷积神经网络&#xff09;的网络结构。 CNN 网络结构, 李宏毅 CNN 主要应用在图像识别&#xff08;image classification, 图像分类&#xff09;领域。 通常&#xff0c;输入的图片大小相同&am…

【Oracle】[INS-30131]执行安装程序验证所需的初始设置失败。

这里写目录标题 一、问题描述1 报错内容1.1 无法从节点“kotin”检索 exectask 的版本1.2 工作目录"xxx"无法在节点"kotin"上使用 2 相关环境2.1 安装软件2.2 安装系统 3 解决思路分析 二、解决方案1 方案一、 满足验证条件 - 不换系统1.1 第一步、检查文件…

uniapp开发微信小程序的巨坑

1、不能使用v-show 2、关于插槽的巨坑 这里我真的是摸索了好久。 小程序版本&#xff1a; hbuilderx版本&#xff1a; 其他版本不知道会不会出现以下情况。 如果组件中带有插槽&#xff0c;那么使用插槽时有以下要注意&#xff1a; 1、如果子组件通过slot&#xff0c;向外…

MySQL数据xtrabackup物理备份方法

目录 一、物理备份的方式二、xtrabackup物理备份1.安装xtrabackup2.完整备份/恢复流程3.增量备份流程4.差异备份流程5.物理备份总结 一、物理备份的方式 1.完整备份 每次对数据进行完整的备份&#xff0c;即对整个数据库的备份、数据库结构和文件结构的备份&#xff0c;保存的…

ADC读取数据进入死循环

结论优先&#xff1a;程序并发处理不当引起寄存器标志位被非预期清除&#xff0c;引起进入死循环。 现象&#xff1a;在进行AD读取数据时&#xff0c;有一个等待ADC转换完成的标志位&#xff0c;概率性卡死在while等待ADC数据转换完成。 static err_t gd32_adc_read(struct d…

Pytorch入门实例的分解写法

数据集是受教育年限和收入,如下图 代码如下 import torch import numpy as np import matplotlib.pyplot as plt import pandas as pddata pd.read_csv(./Income.csv)X torch.from_numpy(data.Education.values.reshape(-1,1).astype(np.float32)) Y torch.from_numpy(data…

python 查找波峰和波谷

import numpy as np import matplotlib.pyplot as plt from scipy.signal import find_peaks# 生成示例信号 x np.array([1, 3, 7, 1, 2, 6, 0, 4, 3, 2, 5, 1])# 寻找波峰 peaks, _ find_peaks(x)# 寻找波谷&#xff08;使用信号的负数形式&#xff09; valleys, _ find_pe…

炒冷饭、语雀崩、领会员-我最主观的一段文字

目录 什么是语雀 语雀&#xff0c;为每一个人提供优秀的文档和知识库工具。 作为一个程序员来说&#xff0c;我们需要一块位置去存储我们正在学习的技术、过往踩过的坑以及正在做的事情&#xff0c;如果我们需要记录每天的TO-DO List&#xff0c;或者需要按照四象限工作法亦或…

瑞虎9:外观够虎,内饰够豪,起售价15.29万

随着更多家庭习惯了全家自驾出行&#xff0c;国内消费者对SUV车型越来越感兴趣。随着生活水平的提高和旅游观念的普及&#xff0c;家庭出行已成为人们生活中的常态。每个家庭成员都希望在出行时能够享受到舒适的感觉&#xff0c;这成为购车时的重要考虑因素。因此&#xff0c;车…

码住!双11支付宝小程序云云市集,享骨折优惠最强购物清单,抽奖赢iPhone 15 Pro!

活动介绍 一年一度的双11狂欢即将拉开序幕&#xff01; 如今的双11不仅是清空购物车的年度盛宴 对于个人开发者和企业来说 也是采购云产品的绝佳时机&#xff01; 今年有什么需要抄作业的购物清单呢&#xff1f; 支付宝小程序云的首次大规模促销活动必须码住&#xff01…

C++初阶(六)类和对象

文章目录 一、 拷贝构造函数1、概念2、特性 二、 赋值运算符重载1、运算符重载2、赋值运算符重载1、赋值运算符重载格式2、 赋值运算符只能重载成类的成员函数不能重载成全局函数3、 用户没有显式实现时&#xff0c;编译器会生成一个默认赋值运算符重载&#xff0c;以值的方式逐…

[ROS系列]ORB_SLAM3错误版本(仅记录)

背景&#xff1a; 1、设备&#xff1a;pc&#xff1b;旭日派x3&#xff08;后续会加上&#xff0c;目前只有pc&#xff09; 2、环境&#xff1a;Ubuntu20.04&#xff1b;ROS2&#xff08;Foxy&#xff09;​​​​​​​ ros2机器人foxy版用笔记本摄像头跑单目orb_slam3-CSD…

142.环形链表

环形链表问题是链表中的经典问题&#xff0c;接下来是142. 环形链表 II - 力扣&#xff08;LeetCode&#xff09; 的描述和详解 。 题目描述&#xff1a; 题目分析&#xff1a; situation1:当链表没有环形结构时&#xff0c;返回空&#xff1a; situation2&#xff1a;当链…

【html】图片多矩形框裁剪

说明 由于项目中需要对一个图片进行多选择框进行裁剪&#xff0c;所以特写当前的示例代码。 代码 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><base href"/"><title>图片裁剪</tit…

【广州华锐互动】智能家居设计3D虚拟还原系统

随着科技的飞速发展&#xff0c;人们对家居生活的需求也在不断提高。智能家居作为一种新兴的生活方式&#xff0c;正逐渐成为现代人追求的理想居住环境。而智能家居设计3D虚拟还原系统&#xff0c;正是为了让人们更好地了解和体验智能家居带来的便捷与舒适&#xff0c;让未来生…

Latex笔记

1. Section 编号方式(数字、字母、罗马)&计数器计数形式修改 IEEE模板中Section的编号是罗马数字&#xff0c;要是改投其他刊物的话可能得用阿拉伯数字&#xff0c;所以可以在导言部分做如下修改&#xff08;放在导言区宏包调用之后&#xff09;&#xff1a; \renewcomma…

AMD大规模裁员15%? 赔偿N+7?官方回应来了 | 百能云芯

近日&#xff0c;美国芯片大厂AMD遭传出在中国进行大规模裁员15%的消息&#xff0c;引发网友关注。 对此&#xff0c;AMD官方26日回应称&#xff0c;「网络传闻失实」&#xff0c;该公司并没有进行大规模裁员。 相反地&#xff0c;AMD是进行的「小幅度」的组织架构优化和重组&a…

使用node创建Web服务

创建Web服务 基于 Node.js 环境&#xff0c;使用内置 http 模块&#xff0c;创建 Web 服务程序 需求&#xff1a;引入 http 模块&#xff0c;使用相关语法&#xff0c;创建 Web 服务程序&#xff0c;响应返回给请求方一句提示 ‘hello&#xff0c;world’ 步骤&#xff1a; 引…