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…...
在软件开发中正确使用MySQL日期时间类型的深度解析
在日常软件开发场景中,时间信息的存储是底层且核心的需求。从金融交易的精确记账时间、用户操作的行为日志,到供应链系统的物流节点时间戳,时间数据的准确性直接决定业务逻辑的可靠性。MySQL作为主流关系型数据库,其日期时间类型的…...

通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...

关键领域软件测试的突围之路:如何破解安全与效率的平衡难题
在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的核心战斗力。不同于普通商业软件,这些承载着国家安全使命的软件系统面临着前所未有的质量挑战——如何在确保绝对安全的前提下,实现高效测试与快速迭代?这一命题正考验着…...

算法笔记2
1.字符串拼接最好用StringBuilder,不用String 2.创建List<>类型的数组并创建内存 List arr[] new ArrayList[26]; Arrays.setAll(arr, i -> new ArrayList<>()); 3.去掉首尾空格...

短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...
SQL慢可能是触发了ring buffer
简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...
scikit-learn机器学习
# 同时添加如下代码, 这样每次环境(kernel)启动的时候只要运行下方代码即可: # Also add the following code, # so that every time the environment (kernel) starts, # just run the following code: import sys sys.path.append(/home/aistudio/external-libraries)机…...

论文阅读笔记——Muffin: Testing Deep Learning Libraries via Neural Architecture Fuzzing
Muffin 论文 现有方法 CRADLE 和 LEMON,依赖模型推理阶段输出进行差分测试,但在训练阶段是不可行的,因为训练阶段直到最后才有固定输出,中间过程是不断变化的。API 库覆盖低,因为各个 API 都是在各种具体场景下使用。…...

通过MicroSip配置自己的freeswitch服务器进行调试记录
之前用docker安装的freeswitch的,启动是正常的, 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...