C++类和对象(下)
✨个人主页: Yohifo
🎉所属专栏: C++修行之路
🎊每篇一句: 图片来源
I do not believe in taking the right decision. I take a decision and make it right.
- 我不相信什么正确的决定。我都是先做决定,然后把事情做好。
文章目录
- 📘前言
- 📘正文
- 📖初始化列表
- 🖋️原初始化方式
- 🖋️使用初始化列表
- 🖋️注意事项
- 📖explicit关键字
- 🖋️隐式转换
- 🖋️限制转换
- 📖static修饰
- 🖋️static在类中
- 📖匿名对象
- 🖋️使用场景
- 📖友元
- 🖋️友元函数
- 🖋️友元类
- 📖内部类
- 🖋️特性
- 📖编译器优化
- 🖋️参数优化
- 🖋️返回优化
- 🖋️编码技巧
- 📖再次理解类和对象
- 📘总结
📘前言
在前两篇关于类和对象的文章中,我们学习了C++类的基本形式、对象的创建与使用以及每个类中都有的六大天选之子:默认成员函数,现在对类的基本框架已经搭好,关于类和对象的学习还存在一些细节,深入理解这些细节就是本文的主要目的

📘正文
先从上篇文章中的结论开始学习

📖初始化列表
初始化列表是祖师爷认证的成员变量初始化位置,初始化列表紧跟在默认构造函数之后,形式比较奇怪:主要通过 : 、, 和 ()实现初始化
class Date
{
public:Date(int year = 1970, int month = 1, int day = 1):_year(year) //以下三行构成初始化列表, _month(month), _day(day){//………}
private:int _year;int _month;int _day;
};
学习初始化列表前先来简单回顾下原初始化方式
🖋️原初始化方式
之前我们的默认构造函数是这样的:
class Date
{
public:Date(int year = 1970, int month = 1, int day = 1){//此时是赋值,变量在使用前,仍然是随机值状态_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;
};
实例化一个对象,调试结果如下
正式赋值前已被初始化为随机值

并且如果我们的成员变量中新增一个 const 修饰的成员:
private:int _year;int _month;int _day;const int _ci
程序运行结果就会变成这样:

直接编译报错了,证明当前初始化方式存在很大问题
原因:
- 原
默认构造函数是以赋值的方式实现“初始化”的 - 被赋值的前提是已存在,而存在必然伴随着
初始化行为 - 此时由编译器负责,也就是编译器的惯用手段:给变量置以
随机值实现初始化 - 成员变量在被赋值前已经被初始化了
const修饰的成员具有常性,只能初始化一次- 也就意味着此时的成员
_ci已经被初始化为随机值,并且被const修饰,具有常性,无法被赋值 - 总结: 原赋值的初始化方式在某些场景下行不通
原赋值初始化方式的缺点:
- 无法给
const修饰成员初始化 - 无法给
引用成员初始化 - 无法给
自定义成员初始化(且该类没有默认构造函数时)
此时祖师爷看不下去了,决定打造一种新的初始化方式:初始化列表,并为初始化列表指定了一个特殊位置:默认构造函数之后

🖋️使用初始化列表
初始化列表基本形式:
- 紧跟在
默认构造函数之后,首先以;开始 - 初始化格式为
待初始化对象(初始值) - 之后待初始化成员都以
,开头 - 不存在结尾符号,除了第一个成员用
;开头外,其他成员都用,开头
class Date
{
public:Date(int year = 1970, int month = 1, int day = 1, const int ci = 0, const int& ref = 0):_year(year) //以下三行构成初始化列表, _month(month), _day(day), _ci(ci) //const 成员能初始化, _ref(ref) //引用成员也能初始化{//………}
private:int _year;int _month;int _day;const int _ci;const int& _ref;
};
在初始化列表的加持下,程序运行结果如下
进入默认构造函数体内时,成员变量已被初始化

初始化列表能完美弥补原赋值初始化的缺点
如此好用的初始化方式为何不用呢?
祖师爷推荐: 尽量使用初始化列表进行初始化,全能又安心
强大的功能靠着周全的规则支撑,初始化列表有很多注意事项(使用规则)
🖋️注意事项
使用方式
;开始,分隔,()内写上初始值
注意
初始化列表中的成员只能出现一次初始化列表中的初始化顺序取决类中的声明顺序- 以下几种类型必须使用
初始化列表进行初始化const修饰引用类型自定义类型,且该自定义类型没有默认构造函数
建议
- 优先选择使用
初始化列表 列表中的顺序与声明时的顺序保持一致
规范使用初始化列表,高高兴兴使用类

📖explicit关键字
explicit 是新的关键字,常用于修饰 默认构造函数,限制隐式转换,使得程序运行更加规范
🖋️隐式转换
所谓隐式转换就算编译器在看到赋值双方类型不匹配时,会将创建一个同类型的临时变量,将 = 左边的值拷贝给临时变量,再拷贝给 = 右边的值,比如:
int a = 10;
double b = 3.1415926;
a = b; //成功赋值,将会截取浮点数 b 的整数部分拷贝给临时变量,再赋值给 a
具体赋值过程如下
需要借助一个同类型的临时变量

将此思想引入类中,假设存在这样一个类:
class A
{
public://默认构造函数A(int a = 0):_a(a){//表示默认构造函数被调用过cout << "A(int a = 0)" << endl;}//默认析构函数~A(){_a = 0;//表示默认析构函数已被调用cout << "~A" << endl;}//拷贝构造函数A(const A& a){_a = a._a;cout << "A(const A& a)" << endl;}//赋值重载函数A& operator=(const A& a){if(this != &a){_a = a._a;}cout << "A& operator=(const A& a)" << endl;return *this;}private:int _a;
};
以下语句的赋值行为是合法的
int main()
{A aa1 = 100; //注:此时整型 100 能赋给自定义类型return 0;
}
合法原因:
- 类中只有一个整型成员
- 赋值时,会先生成同类型临时变量,即调用一次构造函数
- 再调用拷贝构造函数,将临时变量的值拷贝给
aa1

我们可以看看打印结果是否真的如我们想的一样

结果:只调用了一次构造函数
难道编译器偷懒了?
- 并不是,实际这是编译器的优化
- 与其先生成临时变量,再拷贝,不如直接对目标进行构造,这样可以提高效率
这是编译器的优化行为,大多数编译器都支持
看代码会形象些:
A aa1 = 100; //你以为的
A aa1(100); //实际编译器干的,优化!
单参数类赋值时编译器有优化,那么多参数类呢?
class B
{
private:int _a;int _b;int _c;
}
多参数类编译器也会有优化
B bb1 = {1, 2, 3}; //你以为的
B bb1(1, 2, 3); //实际上编译器优化的
编译器是这样认为的:构造临时变量+拷贝构造不如让我直接给你构造
这是编译器针对隐式转换做出的优化行为
不难发现,这样的隐式转换虽然方便,但会影响代码的可读性和规范性,我们可以通过关键字explicit 限制隐式转换行为
🖋️限制转换
在默认构造函数前加上explicit修饰
class A
{
public://默认构造函数//限制隐式转换行为explicit A(int a = 0):_a(a){//表示默认构造函数被调用过cout << "A(int a = 0)" << endl;}
private:int _a;
};
此时再次采用上面那种赋值方式会报错
A aa1 = 100; //报错,此时编译器无法进行隐式类型转换,优化也就不存在了

何时采用 explicit 修饰?
- 想提高代码可读性和规范性时

📖static修饰
static 译为静态的,修饰变量时,变量位于静态区,生命周期增长至程序运行周期
static 有很多讲究,可不敢随便乱用:
- 修饰普通局部变量时,使其能在全局使用
- 修饰全局变量时,破坏其外部链接属性
- static 修饰时,只能被初始化一次
static不能随便乱用

🖋️static在类中
类中被 static 修饰的成员称为 静态成员变量 或 静态成员函数
静态成员为所有类对象所共享,不属于某个具体的对象,存放在静态区静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明- 类
静态成员可用类名::静态成员或者对象.静态成员来访问 静态成员函数没有隐藏的this指针,不能访问任何非静态成员静态成员也是类的成员,受public、protected、private访问限定符的限制
课代表简单总结:
静态成员变量必须在类外初始化(定义)静态成员函数失去了this指针,但当为public时,可以通过类名::函数名直接访问
class Test
{
public://Test(int val = 0, static int sVal = 0)// :_val(val)// , _sVal(sVal) //非法的,初始化列表也无法初始化静态成员变量//{}static void Print(){//cout << _val << endl; //非法的,没有 this 指针,无法访问对象成员cout << _sVal << endl;}
private:int _val;static int _sVal; //静态成员变量
};int Test::_sVal = 0; //静态成员变量必须在类外初始化(定义),需指定属于哪个类
静态成员变量只能初始化一次
静态成员函数没有 this 指针
静态成员函数是为静态成员变量而生
如此刁钻的成员变量究竟有何妙用呢?
- 答: 有的,存在即合理
利用静态成员变量只能初始化一次的特定,写出函数统计程序运行中调用了多少次构造函数
class Test
{
public:Test(int val = 0):_val(val){_sVal++; //利用静态成员变量进行累加统计}static void Print(){cout << _sVal;}
private:int _val = 0;static int _sVal; //静态成员变量
};int Test::_sVal = 0; //静态成员变量必须在类外初始化(定义)int main()
{Test T[10]; //调用十次构造函数//通过静态成员变量验证cout << "程序共调用了";Test::Print();cout << "次成员函数" << endl;return 0;
}
输出结果如下:
得益于 static 修饰的成员变量统计

注意:
静态成员函数不可以调用非静态成员变量,没有this指针非静态成员函数可以调用静态成员变量,具有全局属性
📖匿名对象
C语言结构体支持创建匿名结构体,C++ 则支持创建匿名对象

匿名对象使用如下:
//假设存在日期类 Date
int main()
{Date(); //此处就是一个匿名对象return 0;
}
匿名对象拥有正常对象的所有功能,缺点就是生命周期极短,只有一行
//演示
Date(2023, 2, 10); //匿名对象1 初始化
Date().Print(); //匿名对象2 调用打印函数//注意:两个匿名对象相互独立,创建 匿名对象2 时, 匿名对象1 已被销毁
🖋️使用场景
匿名对象适合用于某些一次性场景,也适合用于优化性能
Date(2023, 2, 10).Print(); //单纯打印日期 2023 2 10//函数返回时
Date d(2002, 1, 1);
return d;
//等价于
return Date(2002, 1, 1); //提高效率
📖友元
新增关键字 friend ,译为朋友,常用于外部函数在类中的友好声明
类中的成员变量为私有,类外函数无法随意访问,但可以在类中将类外函数声明为友元函数,此时函数可以正常访问类中私有成员
友元函数会破坏类域的完整性,有利有弊

注意:
- 友元是单向关系
- 友元不具有传递性
- 友元不能继承
- 友元声明可以写在类中的任意位置
🖋️友元函数
friend 修饰函数时,称为友元函数
class Test
{
public://声明外部函数 Print 为友元函数friend void Print(const Test&d);Test(int val = 100):_val(val){}private:int _val;
};void Print(const Test& d)
{cout << "For Friend " << d._val << endl;
}int main()
{Test t;Print(t);
}
程序正常编译,结果如下:

友元函数可以用来解决外部运算符重载函数无法访问类中成员的问题,但还是不推荐这种方法
🖋️友元类
friend 修饰类时,称为友元类
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;
};
友元有种继承的感觉,但它不是继承,它也不支持继承
📖内部类
将类B写在类A中,B 称作 A 的内部类
class A
{
public://B 称作 A 的内部类class B{private:int _b;}
private:int _a;
}
内部类天生就是外类的友元类
也就是说,B 天生就能访问 A 中的成员
🖋️特性
内部类在C++中比较少用,属于了解型知识
内部类的最大特性就是使得内部类能受到外类的访问限定符限制
内部类特点:
- 独立存在
- 天生就是外类的友元
用途:
- 可以利用内部类,将类隐藏,现实中比较少见
注意:
内部类跟其外类是独立存在的,计算外类大小时,是不包括内部类大小的内部类受访问限定符的限定,假设为私有,内部类无法被直接使用内部类天生就算外类的友元,即可以访问外类中的成员,而外类无法访问内部类
📖编译器优化
前面说过,编译器存在优化行为,这里就来深入探讨一下
把上面的代码搬下来用一下,方便观察发生了什么事情
class A
{
public://默认构造函数A(int a = 0):_a(a){//表示默认构造函数被调用过cout << "A(int a = 0)" << endl;}//默认析构函数~A(){_a = 0;//表示默认析构函数已被调用cout << "~A" << endl;}//拷贝构造函数A(const A& a){_a = a._a;cout << "A(const A& a)" << endl;}//赋值重载函数A& operator=(const A& a){if(this != &a){_a = a._a;}cout << "A& operator=(const A& a)" << endl;return *this;}private:int _a;
};
🖋️参数优化
在类外存在下面这些函数:
void func1(A aa)
{}int main()
{func1(100);return 0;
}
预计调用后发生了这些事情:
构造(隐式转换) -> 拷贝构造(传参) -> 构造(创建aa接收参数)
编译器会出手优化
实际只发生了这些事情:
构造(直接把aa构造为目标值)

🖋️返回优化
除了优化传参外,编译器还会优化返回值
A func2()
{return A(100);
}int main()
{//func1(100);A a = func2();return 0;
}
预计调用后发生了这些事情:
构造(匿名对象的创建) -> 构造(临时变量) -> 拷贝构造(将匿名对象拷贝给临时变量) -> 拷贝构造(将临时变量拷贝给 a)
编译器会出手优化
实际只发生了这些事情:
构造(直接把函数匿名对象值看作目标值,构造除出 a)

现在可以证明:编译器会将某些非必要的步骤省略点,执行关键步骤
优化场景:
- 涉及
拷贝构造+构造时,编译器多会出手 - 传值返回时,涉及
多次拷贝构造,编译器也会出手
注意:
- 引用传参时,编译器无需优化,因为
不会涉及拷贝构造 - 实际编码时,如果能采用匿名构造,就用匿名构造,会
加速编译器的优化 - 接收参数时,如果分成两行(先定义、再接收),编译器无法优化,效率会降低
编译器只能在一行语句内进行优化,如果涉及多条语句,编译器也不敢擅自主张
🖋️编码技巧
下面是一些编码小技巧,可以提高程序运行效率
- 接收返回值对象时,尽量拷贝构造方式接收,不要赋值接收
- 函数返回时,尽量返回匿名对象
- 函数参数尽量使用
const&参数

📖再次理解类和对象

出自:比特教育科技
📘总结
以上就是 类和对象(下)的全部内容了,我们在本文章学习了一些类和对象的小细节,比如明白了善用初始化列表的道理、懂得了友元函数的用法、了解了编译器的优化事实、最后还简单理解了类和对象与现实的关系,相信在这些细节的加持之下,对类和对象的理解能更上一层楼!
如果你觉得本文写的还不错的话,可以留下一个小小的赞👍,你的支持是我分享的最大动力!
如果本文有不足或错误的地方,随时欢迎指出,我会在第一时间改正

…
相关文章推荐
类和对象(上)
类和对象(中)
C++入门基础
![]()
相关文章:
C++类和对象(下)
✨个人主页: Yohifo 🎉所属专栏: C修行之路 🎊每篇一句: 图片来源 I do not believe in taking the right decision. I take a decision and make it right. 我不相信什么正确的决定。我都是先做决定,然后把…...
Java常见的六种线程池、线程池-四种拒绝策略总结
点个关注,必回关 一、线程池的四种拒绝策略: CallerRunsPolicy - 当触发拒绝策略,只要线程池没有关闭的话,则使用调用线程直接运行任务。 一般并发比较小,性能要求不高,不允许失败。 但是,由于…...
Node=>Express中间件分类 学习4
1.中间件分类 应用级别的中间件路由级别的中间件错误级别的中间件Express 内置的中间件第三方的中间件 通过app.use()或app.get()或app.post()绑定到app实力上的中间件,叫做应用级别的中间件 …...
在阿里当外包,是一种什么工作体验?
上周和在阿里做外包的朋友一起吃饭,朋友吃着吃着,就开启了吐槽模式。 他一边喝酒一边说,自己现在做着这份工作,实在看不到前途。 看他状态不佳,问了才知道,是手上的项目太磨人。 他们现在做的项目&#…...
Vue3快速入门【二】
Vue3快速入门一、传值父传子,子传父v-model二、插槽2.1、匿名插槽2.2、具名插槽2.3、插槽作用域2.4、插槽作用域案例2.4.1、初始布局2.4.2、插槽使用2.4.3、点击编辑按钮获取本行数据(插槽作用域的使用)2.4.4、类型书写优化2.4.5、全局接口抽…...
C++-类和对象(上)
类和对象(上)一,构造函数1,概念2,特性二,析构函数1,概念2,特性三,拷贝构造1,概念2,特性四,运算符重载1,概念2,…...
CAPL(vTESTStudio) - DoIP - TCP接收_04
TCP接收 函数介绍 TcpOpen函数...
联合培养博士经历对于国内就业有优势吗?
2023年国家留学基金委(CSC)申请在即,很多在读博士在关心申报的同时,也对联培经历能否有助于国内就业心中存疑,故此知识人网小编重点解答此问题。之前,我们在“CSC联合培养-国内在读博士出国的绝佳选择”一文…...
测试左移之需求质量
测试左移的由来 缺陷的修复成本逐步升高 下面是质量领域司空见惯的一张图,看图说话,容易得出:大部分缺陷都是早期引入的,同时大部分缺陷都是中晚期发现的,而缺陷发现的越晚,其修复成本就越高。因此&#…...
【数据结构初阶】第三节.顺序表详讲
文章目录 前言 一、顺序表的概念 二、顺序表功能接口概览 三、顺序表基本功能的实现 四、四大功能 1、增加数据 1.1 头插法: 1.2 尾插法 1.3 指定下标插入 2、删除数据 2.1 头删 2.2 尾删 2.3 指定下标删除 2.4 删除首次出现的指定元素 3、查找数据…...
新手小白适合做跨境电商吗?
今天的跨境电商已经逐渐成熟,靠运气赚钱的时代早已过去,馅饼不可能从天上掉下来,尤其是你想做一个没有货源的小白劝你醒醒。做跨境电商真的不容易,要想做,首先要分析自己是否适合做。米贸搜整理了以下资料,…...
Python搭建自己[IP代理池]
IP代理是什么:ip就是访问网页数据服务器位置信息,每一个主机或者网络都有一个自己IP信息为什么要使用代理ip:因为在向互联网发送请求中,网页端会识别客户端是真实用户还是爬虫程序,在今天以互联网为主导的世界中&#…...
pandas——plot()方法可视化
pandas——plot()方法可视化 作者:AOAIYI 创作不易,如果觉得文章不错或能帮助到你学习,记得点赞收藏评论哦 在此,感谢你的阅读 文章目录pandas——plot()方法可视化一、实验目的二、实验原理三、实验环境四、实验内容五、实验步骤…...
【Three.js基础】坐标轴辅助器、requestAnimationFrame处理动画、Clock时钟、resize页面尺寸(二)
🐱 个人主页:不叫猫先生 🙋♂️ 作者简介:前端领域新星创作者、阿里云专家博主,专注于前端各领域技术,共同学习共同进步,一起加油呀! 💫系列专栏:vue3从入门…...
C++之完美转发、移动语义(forward、move函数)
完美转发1. 在函数模板中,可以将自己的参数“完美”地转发给其它函数。所谓完美,即不仅能准确地转发参数的值,还能保证被转发参数的左、右值属性不变。2. C11标准引入了右值引用和移动语义,所以,能否实现完美转发&…...
LeetCode刷题系列 -- 48. 旋转图像
给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。示例 1:输入:matrix [[1,2,3],[4,5,6],[7,8,9]]输出&#…...
在多线程环境下使用哈希表
一.HashTable和HashMapHashTable是JDK1.0时创建的,其在创建时考虑到了多线程情况下存在的线程安全问题,但是其解决线程安全问题的思路也相对简单:在其众多实现方法上加上synchronized关键字(效率较低),保证…...
【排序算法】堆排序(Heap Sort)
堆排序是指利用堆这种数据结构所设计的一种排序算法。堆是一个近似完全二叉树的结构,并同时满足堆积的性质:即子结点的键值或索引总是小于(或者大于)它的父节点。堆排序介绍学习堆排序之前,有必要了解堆!若…...
分类预测 | Matlab实现SSA-RF和RF麻雀算法优化随机森林和随机森林多特征分类预测
分类预测 |Matlab实现SSA-RF和RF麻雀算法优化随机森林和随机森林多特征分类预测 目录分类预测 |Matlab实现SSA-RF和RF麻雀算法优化随机森林和随机森林多特征分类预测分类效果基本介绍模型描述程序设计参考资料分类效果 基本介绍 Matlab实现SSA-RF和RF麻雀算法优化随机森林和随机…...
Allegro如何添加ICT操作指导
Allegro如何添加ICT操作指导 当PCB板需要做飞针测试的时候,通常需要在PCB设计的时候给需要测试的网络添加上ICT。 如图: Allegro支持给网络添加ICT,具体操作如下 首先在库中创建一个阻焊开窗的过孔,比如via10-ict一般阻焊开窗的尺寸比盘单边大2mil 在PCB中选择Manufacture…...
KubeSphere 容器平台高可用:环境搭建与可视化操作指南
Linux_k8s篇 欢迎来到Linux的世界,看笔记好好学多敲多打,每个人都是大神! 题目:KubeSphere 容器平台高可用:环境搭建与可视化操作指南 版本号: 1.0,0 作者: 老王要学习 日期: 2025.06.05 适用环境: Ubuntu22 文档说…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...
CMake 从 GitHub 下载第三方库并使用
有时我们希望直接使用 GitHub 上的开源库,而不想手动下载、编译和安装。 可以利用 CMake 提供的 FetchContent 模块来实现自动下载、构建和链接第三方库。 FetchContent 命令官方文档✅ 示例代码 我们将以 fmt 这个流行的格式化库为例,演示如何: 使用 FetchContent 从 GitH…...
dify打造数据可视化图表
一、概述 在日常工作和学习中,我们经常需要和数据打交道。无论是分析报告、项目展示,还是简单的数据洞察,一个清晰直观的图表,往往能胜过千言万语。 一款能让数据可视化变得超级简单的 MCP Server,由蚂蚁集团 AntV 团队…...
AI,如何重构理解、匹配与决策?
AI 时代,我们如何理解消费? 作者|王彬 封面|Unplash 人们通过信息理解世界。 曾几何时,PC 与移动互联网重塑了人们的购物路径:信息变得唾手可得,商品决策变得高度依赖内容。 但 AI 时代的来…...
Java后端检查空条件查询
通过抛出运行异常:throw new RuntimeException("请输入查询条件!");BranchWarehouseServiceImpl.java // 查询试剂交易(入库/出库)记录Overridepublic List<BranchWarehouseTransactions> queryForReagent(Branch…...
结构化文件管理实战:实现目录自动创建与归类
手动操作容易因疲劳或疏忽导致命名错误、路径混乱等问题,进而引发后续程序异常。使用工具进行标准化操作,能有效降低出错概率。 需要快速整理大量文件的技术用户而言,这款工具提供了一种轻便高效的解决方案。程序体积仅有 156KB,…...
spring boot使用HttpServletResponse实现sse后端流式输出消息
1.以前只是看过SSE的相关文章,没有具体实践,这次接入AI大模型使用到了流式输出,涉及到给前端流式返回,所以记录一下。 2.resp要设置为text/event-stream resp.setContentType("text/event-stream"); resp.setCharacter…...
基于 HTTP 的单向流式通信协议SSE详解
SSE(Server-Sent Events)详解 🧠 什么是 SSE? SSE(Server-Sent Events) 是 HTML5 标准中定义的一种通信机制,它允许服务器主动将事件推送给客户端(浏览器)。与传统的 H…...

