C++ 类和对象(中)
1.类的六个默认成员函数
如果一个类中什么成员都没有,简称为空类。
空类中真的什么都没有吗?其实并不是,任何类在什么都不写时,编译器会自动生成以下六个默认成员函数。
默认成员函数:用户没有显式实现,编译器会生成的成员函数成为默认成员函数。
class Date {};
2.构造函数
2.1概念
对于下面这个类
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(2024, 12, 5);d1.Print();Date d2;d2.Init(2025, 1, 11);d2.Print();return 0;
}
对于Date类,可以通过 Init 共有方法给对象设置日期,但如果每次创建对象时都调用该方法设置信息,未免有点麻烦,那能否在对象创建时,就将信息设置进去呢?
构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,以保证每个数据成员都有一个合适的初始值,并且在对象整个生命周期内只调用一次。
2.2特性
构造函数是特殊的成员函数,需要注意的是,构造函数虽然名字叫构造,但是构造函数的主要任务并不是开辟空间创建对象,而是初始化对象。
其特征如下:
- 函数名与类名相同
- 无返回值
- 对象实例化时编译器自动调用对应的构造函数
- 构造函数可以重载
class Date { public://无参构造函数Date(){};//带参构造函数Date(int year,int month,int day){_year = year;_month = month;_day = day;} private:int _year;int _month;int _day; }; int main() {Date d1;//调用无参构造函数Date d2(2025, 1, 11);//调用带参构造函数Date d3();//如果通过无参构造函数创建对象时,//对象后面不用跟括号,否则就成了函数声明。//导致编译器无法区分d3是对象还是函数名。return 0; }
- 如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成。
class Date { public:/*//如果用户显式定义了构造函数,编译器将不再生成Date(int year, int month, int day){_year = year;_month = month;_day = day;}*/ private:int _year;int _month;int _day; }; int main() {Date d1;//调用无参构造函数//error C2512: “Date”: 没有合适的默认构造函数可用//编译失败,因为一旦显式定义了构造函数,编译器将不再生成。//但将类中构造函数注释后,代码可以编译通过,//因为用户没有显式定义,编译器自动生成一个无参构造函数。return 0; }
- C++把类型分成内置类型(基本类型)和自定义类型。内置类型就是语言提供的数据类型,如:int/char...,自定义类型就是我们使用 class/struct/union 等自己定义的类型。
我们不写编译器默认生成构造函数,内置类型不做处理(有些编译器也会处理,但那是个性化行为,不是所有的编译器都会处理的,我们应该默认都不处理),自定义类型会去调用它的默认构造。
a.一般情况下,有内置类型成员,就需要自己写构造函数。
b.全部是自定义类型,可以考虑让编译器自己生成。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;//编译器生成默认的构造函数会对自定义类型成员_t//调用它的默认成员函数。 }; int main() {Date d;return 0; }
运行结果:
注意:C++11中针对内置类型成员不做初始化的缺陷,打了补丁:内置成员变量在类中声明时可以给默认值。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=2025; //不是初始化,这里只是声明,给的是默认缺省值,int _month=1; //给编译器生成默认构造函数使用的。int _day=11;//自定义类型Time _t; }; int main() {Date d;return 0; }
结论:
1.一般情况下,构造函数都需要我们自己写。
除非:
(1)内置类型成员都有缺省值,且初始化都符合我们的要求。
(2)全是自定义类型的构造,且这些类型都定义默认构造。
3.析构函数
3.1概念
析构函数:与构造函数相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由编译器完成的。而对象在销毁时自动调用析构函数,完成对象中资源的清理工作。
3.2特性
析构函数是特殊的成员函数,其特征如下:
- 析构函数名是在类名前面加上字符~
- 无参数无返回值类型
- 一个类只能有一个析构函数。若未显式定义,编译器会自动生成默认的析构函数。注意:析构函数不能重载。
- 对象生命周期结束时,C++编译器自动调用析构函数。
- 编译器生成的默认析构函数,对自定义类型成员调用它的析构函数。对内置类型成员不做处理。
class Time { public:~Time(){cout << "~Time()" << endl;} 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()在main方法中根本没有直接创建Time类的对象,为什么最后会调用Time类的析构函数?因为:main方法中创建了Date对象d,而d中包含4个成员变量,其中 _year,_month, day三个是内置类型成员,销毁时不需要资源清理,最后系统直接将其内存回收即可;
而 _t 是Time类对象,所以在 d 销毁时,要将其内部包含的Time类的 _t对象销毁,所以要调用Time类的析构函数。但是main函数中不能直接调用Time类的析构函数,实际要释放的是Date类对象,所以编译器会调用Date类的析构函数,而Date没有显式提供,则编译器会给Date类生成一个默认的析构函数,目的是在其内部调用Time类的析构函数,即当Date对象销毁时,要保证其内部每个自定义对象都可以正确销毁。main函数中并没有直接调用Time类析构函数,而是显式调用编译器为Date类生成的默认析构函数
注意:创建哪个类的对象则调用该类的构造函数,销毁哪个类的对象则调用该类的析构函数。 -
如果类中没有申请资源时,析构函数可以不写,直接使用编译器生成的默认析构函数;有资源申请时,一定要写,否则会造成资源泄露。
4.拷贝构造函数
4.1概念
拷贝构造函数:只有单个形参,该形参是对类类型对象的引用(一般用const修饰),在用已存在的类类型对象创建新对象时由编译器自动调用。
(用一个已经存在的对象初始化另一个对象)
4.2特征
拷贝构造函数也是特殊的成员函数,其特征:
- 拷贝构造函数是构造函数的一个重载形式
- 拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错,因为会引发无穷递归调用。
class Date { public:Date(int year=2024, int month=12, int day=5){_year = year;_month = month;_day = day;}//Date(const Date d)//错误写法Date(const Date& d){_year = d._year;_month = d._month;_day = d._day;} private:int _year;int _month;int _day; }; int main() {Date d1;Date d2(d1);//规定自定义类型,必须要调用拷贝构造去完成。return 0; //内置类型直接拷贝 }
-
若未显式定义,编译器会生成默认的拷贝构造函数。默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝或者值拷贝。内置类型按照字节方式直接拷贝的,而自定义类型是调用其拷贝构造函数完成拷贝的。
-
编译器生成的默认拷贝构造函数已经可以完成字节序的值拷贝了。那我们还需要自己实现吗?
typedef int Datatype; struct Stack {Stack(size_t capacity=10){_array = (Datatype*)malloc(sizeof(Datatype) * capacity);if (_array == nullptr){perror("malloc申请空间失败");return;}_capacity = capacity;_size = 0;}void Push(const Datatype& data){//扩容_array[_size] = data;++_size;}~Stack(){if (_array){free(_array);_array = nullptr;_capacity = 0;_size = 0;}}Datatype* _array;size_t _capacity;size_t _size; };int main() {Stack s;s.Push(1);s.Push(2);s.Push(3);Stack s1(s);return 0; }
执行结果:程序崩溃
注意:类中如果没有涉及到资源申请时,拷贝构造函数是否写都可以;一旦涉及到资源申请时,则拷贝构造函数是一定要写的,否则就是浅拷贝,发生上述程序崩溃问题。 -
拷贝构造函数典型调用场景
1) 使用已存在对象创建新对象
2) 函数参数类型为类类型对象
3) 函数返回值类型为类类型对象class Date { public:Date(int year,int month,int day)//构造函数{cout << "Date(int,int,int):" << this << endl;}Date(const Date& d)//拷贝构造函数{cout << "Date(const Date& d):" << this << endl;}~Date()//析构函数{cout << "~Date():" << this << endl;} private:int _year;int _month;int _day; };Date Test(Date d) {Date tmp(d);return tmp; } int main() {Date d1(2024, 12, 7);Test(d1);return 0; }
为了提高程序效率,一般对象传参时,尽量使用引用类型,返回时根据使用场景,能用引用尽量使用引用。出了函数作用域对象或变量还没销毁就可以使用引用。
5.赋值运算符重载
5.1运算符重载
C++为了增强代码的可读性引入了运算符重载,运算符重载是具有特殊函数名的函数,也具有其返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。
函数名字:关键字operator后面接需要重载的运算符符号
函数原型:返回值类型 operator 操作符 (参数列表)
注意:
- 不能通过连接其他符号创建新的操作符:比如operator@...
- 重载操作符必须有一个类类型参数(自定义类型)
- 用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不能改变其含义
- 作为类成员函数重载时,其形参看起来比操作数目少一个,因为成员函数的第一个参数为隐藏的this
- .* :: sizeof ?: . 注意这五个运算符不能重载
- 是否要重载运算符,看这个运算符对这个类是否有意义
class Date { public:Date(int year = 2024, int month = 12, int day = 7){_year = year;_month = month;_day = day;}//private:int _year;int _month;int _day; }; //运算符重载成全局的就需要成员变量是公有的,这样就不能保证封装性了?! //后面我们可以用友元函数解决,或者重载成为成员函数 bool operator==(const Date& d1, const Date& d2) {return d1._year == d2._year&& d1._month == d2._month&& d1._day == d2._day; } int main() {Date d1(2020, 2, 2);Date d2(2020, 2, 2);cout << (d1 == d2) << endl;//会转换成operator==(d1,d2)return 0; }
5.2赋值运算符重载
1.赋值运算符重载格式
- 参数类型:const T&,传递引用可以提高传参效率
- 返回值类型:T&,返回引可以提高返回的效率,有返回值的目的是为了支持连续赋值
- 检测是否自己给自己赋值
- 返回*this:要符合连续赋值的含义
class Date
{
public:Date(int year = 2024, int month = 12, int day = 7){_year = year;_month = month;_day = day;}Date& operator=(const Date& d){if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;}
private:int _year;int _month;int _day;
};
int main()
{Date d1(2020, 2, 2);Date d2(2024, 1, 1);d2 = d1;//d2.operator(d1)return 0;
}
运算符重载函数:已经存在的两个对象之间的复制拷贝。
拷贝构造函数:用一个已经存在的对象初始化另一个对象。
2.赋值运算符只能重载成类的成员函数不能重载成全局函数
原因:赋值运算符如果不显式实现,编译器就会生成一个默认的。此时用户再在类外自己实现一个全局的赋值运算符重载,就和编译器生成的默认赋值运算符重载冲突了,所以赋值运算符重载只能是类的成员函数。
3.用户没有显式实现时,编译器会生成一个默认复制运算符重载,以值的方式逐字节拷贝。注意:内置类型成员是直接赋值的,而自定义类型成员变量需要调用对应类的赋值运算符重载完成赋值。
如果类中未涉及到资源管理,赋值运算符是否实现都可以;一旦涉及到资源管理则必须要实现。
typedef int Datatype;
struct Stack
{Stack(size_t capacity=10){_array = (Datatype*)malloc(sizeof(Datatype) * capacity);if (_array == nullptr){perror("malloc申请空间失败");return;}_capacity = capacity;_size = 0;}void Push(const Datatype& data){//扩容_array[_size] = data;++_size;}~Stack(){if (_array){free(_array);_array = nullptr;_capacity = 0;_size = 0;}}Datatype* _array;size_t _capacity;size_t _size;
};int main()
{Stack s1;s1.Push(1);s1.Push(2);s1.Push(3);s1.Push(4);Stack s2;s2 = s1;return 0;
}
5.3前置++和后置++重载
class Date
{
public:Date(int year = 2024, int month = 12, int day = 7){_year = year;_month = month;_day = day;}//前置++:返回+1之后的结果//this指向的对象函数结束之后不会销毁,所以以引用返回提高效率Date& operator++(){_day += 1;return *this;}//C++规定:后置++重载时多增加一个int类型的参数,//但调用函数时该参数不用传递,编译器自动传递。//为了让前置++和后置++能正确重载Date operator++(int)//参数占位,形成函数重载{Date tmp(*this);_day += 1;return tmp;}
private:int _year;int _month;int _day;
};
int main()
{Date d1(2020, 2, 2);Date d2(2024, 1, 1);d1++;++d2;return 0;
}
6.日期类的实现
class Date
{
public://获取天数int GetMonthDay(int year, int month){static int days[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };int day = days[month];if (month == 2 && ((year % 4 == 0 && year % 100 != 0) && (year % 400 == 0))){day+=1;}return day;}//全缺省构造函数Date(int year = 2024, int month = 12, int day = 8){_year = year;_month = month;_day = day;}//拷贝构造函数Date(const Date& d){_year = d._year;_month = d._month;_day = d._day;}//赋值运算符重载//d2=d3 -> d2.operator=(&d2,d3)Date& operator=(const Date& d){if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;}//析构函数~Date(){}//日期+=天数Date& operator+=(int day){_day += day;while (_day > GetMonthDay(_year,_month)){_day -= GetMonthDay(_year, _month);_month++;if (_month == 13){_year++;_month = 1;}}return *this;}//日期+天数Date operator+(int day){Date tmp(*this);tmp += day;//复用return tmp;}//日期-=天数Date& operator-=(int day){if (_day > day){_day -= day;return *this;}_day -= day;while (_day <= 0){_day += GetMonthDay(_year, _month);_month--;if (_month == 0){_year--;_month = 12;}}}//日期-天数Date operator-(int day){Date tmp(*this);tmp -= day;return tmp;}//前置++:返回+1之后的结果//this指向的对象函数结束之后不会销毁,所以以引用返回提高效率Date& operator++(){_day += 1;if (_day > GetMonthDay(_year, _month)){_day -= GetMonthDay(_year, _month);_month += 1;if (_month == 13)_year++;}return *this;}//C++规定:后置++重载时多增加一个int类型的参数,//但调用函数时该参数不用传递,编译器自动传递。//为了让前置++和后置++能正确重载Date operator++(int)//参数占位,形成函数重载{Date tmp(*this);_day += 1;if (_day > GetMonthDay(_year, _month)){_day -= GetMonthDay(_year, _month);_month += 1;if (_month == 13)_year++;}return tmp;}//后置--Date operator--(int){Date tmp(*this);_day -= 1;return tmp;}//前置--Date& operator--(){_day -= 1;return *this;}//>运算符重载bool operator>(const Date& d){if (_year > d._year)return true;else if (_year == d._year && _month > d._month)return true;else if (_year == d._year && _month == d._month && _day > d._day)return true;return false;}//==运算符重载bool operator==(const Date& d){if (_year == d._year && _month == d._month && _day == d._day)return true;return false;}//>=运算符重载bool operator>=(const Date& d){return (*this > d || *this == d);//复用}//<运算符重载bool operator<(const Date& d){return !(*this >= d);}//<=运算符重载bool operator<=(const Date& d){return !(*this > d);}//!=运算符重载bool operator!=(const Date& d){return !(*this == d);}
private:int _year;int _month;int _day;
public://友元函数friend ostream& operator<<(ostream& os, const Date& d);
};
ostream& operator<<(ostream& os, const Date& d) {os << d._year << "-" << d._month << "-" << d._day; return os;
}
int main()
{Date d1(2024, 2, 8);Date d2(2024, 2, 9);//d1 += 51;cout << d1 << endl;//cout << d1 + 51<<endl;cout << (d1 - 9) << endl;//cout << ++d1 <<endl;cout << (d1 > d2) << endl;cout << (d1 >= d2) << endl;cout << (d1 < d2) << endl;cout << (d1 <= d2) << endl;return 0;
}
7.const成员
将const修饰的“成员函数”称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员函数进行修改。
权限可以缩小但是不能放大:
const对象不可以调用非const成员函数。
非const对象可以调用const成员函数。
8.取地址及const取地址操作符重载
这两个默认成员函数一般不用定义,编译器会默认生成。
class Date
{
public:Date* operator&(){return this;}const Date* operator&()const{return this;}
private:int _year;int _month;int _day;
};
这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可,只有特殊情况,才需要重载,比如想让别人获取到指定的内容。
相关文章:

C++ 类和对象(中)
1.类的六个默认成员函数 如果一个类中什么成员都没有,简称为空类。 空类中真的什么都没有吗?其实并不是,任何类在什么都不写时,编译器会自动生成以下六个默认成员函数。 默认成员函数:用户没有显式实现,编…...

在做题中学习(79):最小K个数
解法:快速选择算法 说明:堆排序也是经典解决问题的算法,但时间复杂度为:O(NlogK),K为k个元素 而将要介绍的快速选择算法的时间复杂度为: O(N) 先看我的前两篇文章,分别学习:数组分三块&#…...
spark3 sql优化:同一个表关联多次,优化方案
目录 1.合并查询2.使用 JOIN 条件的过滤优化3.使用 Map-side Join 或 Broadcast Join4.使用 Partitioning 和 Bucketing5.利用 DataFrame API 进行优化假设 A 和 B 已经加载为 DataFramePerform left joins with specific conditions6.使用缓存或持久化7.避免笛卡尔积总结 1.合…...

JavaWeb学习(4)(四大域、HttpSession原理(面试)、SessionAPI、Session实现验证码功能)
目录 一、web四大域。 (1)基本介绍。 (2)RequestScope。(请求域) (3)SessionScope。(会话域) (4)ApplicationScope。(应用域) (5)PageScope。(页面域) 二、Ht…...

Ubuntu22.04系统源码编译OpenCV 4.10.0(包含opencv_contrib)
因项目需要使用不同版本的OpenCV,而本地的Ubuntu22.04系统装了ROS2自带OpenCV 4.5.4的版本,于是编译一个OpenCV 4.10.0(带opencv_contrib)版本,给特定的项目使用,这就不用换个设备后重新安装OpenCV 了&…...

【Unity高级】在编辑器中如何让物体围绕一个点旋转固定角度
本文介绍如何在编辑器里让物体围绕一个点旋转固定角度,比如上图里的Cube是围绕白色圆盘的中心旋转45度的。 目标: 创建一个在 Unity 编辑器中使用的旋转工具,使开发者能够在编辑模式下快速旋转一个物体。 实现思路: 编辑模式下…...

2024.11.29——[HCTF 2018]WarmUp 1
拿到题,发现是一张图,查看源代码发现了被注释掉的提示 <!-- source.php--> step 1 在url传参看看这个文件,发现了这道题的源码 step 2 开始审计代码,分析关键函数 //mb_strpos($haystack,$needle,$offset,$encoding):int|…...
AGameModeBase和游戏模式方法
AGameModeBase和游戏模式方法有着密切的关系: AGameModeBase是游戏模式的基础类: 它提供了控制游戏规则的基本框架包含了一系列管理游戏流程的核心方法是所有自定义游戏模式类的父类 主要的游戏模式方法包括: // 游戏初始化时调用 virtua…...
Swift 扩展
Swift 扩展 Swift 是一种强大的编程语言,由苹果公司开发,用于iOS、macOS、watchOS和tvOS应用程序的开发。自2014年发布以来,Swift因其易于阅读和编写的语法、现代化的设计以及出色的性能而广受欢迎。本文将探讨Swift的一些关键特性ÿ…...

【NebulaGraph】官方查询语言nGQL教程1 (四)
【NebulaGraph】官方查询语言nGQL教程1 1. 课程信息2. 查找路径FIND PATH2.1 补充说明FIND PATH2.2 例子 1. 课程信息 课程地址: https://www.bilibili.com/video/BV1PT411P7w8/?spm_id_from333.337.search-card.all.click&vd_source240d9002f7c7e3da63cd9a975639409a …...

阿里云负载均衡SLB实践
基于上篇文章继续,如果你使用的是阿里云等云平台,通过配置nginxkeepAlived行不通,因为阿里云服务器不支持你虚拟出ip提供给外部访问,需要使用阿里云的负载均衡产品 对应的产品有三个系列 1、应用场景 ALB: 主要是对应应用层的7层…...
鸿蒙技术分享:❓❓[鸿蒙应用开发]怎么更好的管理模块生命周期?
鸿蒙HarmonyOS NEXT应用开发架构设计-模块生命周期管理 模块化开发 模块化开发已经是应用开发中的一个共识,一般对于公司级的应用开发,都会考虑是否可以进行模块化开发。 HarmonyOS NEXT系统应用开发目前使用的Stage模型其实就有涉及模块化开发的部分…...

深度解析 Ansible:核心组件、配置、Playbook 全流程与 YAML 奥秘(上)
文章目录 一、ansible的主要组成部分二、安装三、相关文件四、ansible配置文件五、ansible 系列 一、ansible的主要组成部分 ansible playbook:任务剧本(任务集),编排定义ansible任务集的配置文件,由ansible顺序依次执…...

LabVIEW气缸摩擦力测试系统
基于LabVIEW的气缸摩擦力测试系统实现了气缸在不同工作状态下摩擦力的快速、准确测试。系统由硬件平台和软件两大部分组成,具有高自动化、精确测量和用户友好等特点,可广泛应用于精密机械和自动化领域。 项目背景: 气缸作为舵机关键部件…...
Leetcode. 688骑士在棋盘上的概率
题目描述 原题链接:Leetcode. 688骑士在棋盘上的概率 解题思路 多元dp 将dp[step][i][j])定义为从(i, j)出发,走step步之后骑士还在棋盘上的概率。 如果 ( i , j ) (i,j) (i,j)不在棋盘上,即非 0 < i < n 0<i<n 0<i<…...
TCP/IP 协议栈高效可靠的数据传输机制——以 Linux 4.19 内核为例
TCP/IP 协议栈是一种非常成熟且广泛使用的网络通信框架,它将复杂的网络通信任务分成多个层次,从而简化设计,使每一层的功能更加清晰和独立。在经典的 TCP/IP 协议栈中,常见的分层为链路层、网络层、传输层和应用层。本文将对每一层的基本功能进行描述,并列出对应于 Linux …...

Ubuntu22.04搭建LAMP环境(linux服务器学习笔记)
目录 引言: 一、系统更新 二、安装搭建Apache2 1.你可以通过以下命令安装它: 2.查看Apache2版本 3.查看Apache2运行状态 4.浏览器访问 三、安装搭建MySQL 1.安装MySQL 2.查看MySQL 版本 3.安全配置MySQL 3.1是否设置密码?(按y|Y表…...
鸿蒙面试---1208
HarmonyOS 三大技术理念 分布式架构:HarmonyOS 的分布式架构使得设备之间能够无缝协同工作。例如,它允许用户在不同的智能设备(如手机、平板、智能手表等)之间共享数据和功能。比如,用户可以在手机上开始编辑文档&…...
java基础教程第16篇( 正则表达式)
Java 正则表达式 正则表达式定义了字符串的模式。 正则表达式可以用来搜索、编辑或处理文本。 正则表达式并不仅限于某一种语言,但是在每种语言中有细微的差别。 Java 提供了 java.util.regex 包,它包含了 Pattern 和 Matcher 类,用于处理正…...

Docker部署的gitlab升级的详细步骤(升级到17.6.1版本)
文章目录 一、Gitlab提示升级信息二、老版本的docker运行gitlab命令三、备份老版本Gitlab数据四、确定升级路线五、升级(共分3个版本升级)5.1 升级第一步(17.1.2 > 17.3.7)5.2 升级第二步(17.3.7 > 17.5.3)5.3 升级第三步(17.5.3 > 17.6.1) 六、web端访问gitlab服务 一…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...

3.3.1_1 检错编码(奇偶校验码)
从这节课开始,我们会探讨数据链路层的差错控制功能,差错控制功能的主要目标是要发现并且解决一个帧内部的位错误,我们需要使用特殊的编码技术去发现帧内部的位错误,当我们发现位错误之后,通常来说有两种解决方案。第一…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
Python爬虫(二):爬虫完整流程
爬虫完整流程详解(7大核心步骤实战技巧) 一、爬虫完整工作流程 以下是爬虫开发的完整流程,我将结合具体技术点和实战经验展开说明: 1. 目标分析与前期准备 网站技术分析: 使用浏览器开发者工具(F12&…...

Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

短视频矩阵系统文案创作功能开发实践,定制化开发
在短视频行业迅猛发展的当下,企业和个人创作者为了扩大影响力、提升传播效果,纷纷采用短视频矩阵运营策略,同时管理多个平台、多个账号的内容发布。然而,频繁的文案创作需求让运营者疲于应对,如何高效产出高质量文案成…...

Web后端基础(基础知识)
BS架构:Browser/Server,浏览器/服务器架构模式。客户端只需要浏览器,应用程序的逻辑和数据都存储在服务端。 优点:维护方便缺点:体验一般 CS架构:Client/Server,客户端/服务器架构模式。需要单独…...

链式法则中 复合函数的推导路径 多变量“信息传递路径”
非常好,我们将之前关于偏导数链式法则中不能“约掉”偏导符号的问题,统一使用 二重复合函数: z f ( u ( x , y ) , v ( x , y ) ) \boxed{z f(u(x,y),\ v(x,y))} zf(u(x,y), v(x,y)) 来全面说明。我们会展示其全微分形式(偏导…...