第四讲:类与对象(下)
目录
1、再谈构造函数
1.1、构造函数体赋值
1.2、初始化列表
1.3、explicit关键字
2、static成员
3、友元
3.1、友元函数
3.2、友元类
4、内部类
5、匿名对象
6、拷贝对象时的优化(了解)
7、重新理解类与对象
8、日期类的实现
9、练习题
9.1、第一题
9.2、第二题
9.3、第三题
9.4、第四题
9.5、第五题
1、再谈构造函数
1.1、构造函数体赋值
在创建对象时,编译器通过调用构造函数,给对象中各个成员变量一个合适的初始值。
例如:
class Date
{
public:Date(int year, int month, int day){_year = year;_month = month;_day = day;}
private:int _year;int _month;int _day;
};
虽然上述构造函数调用之后,对象中已经有了一个初始值,但是不能将其称为对对象中成员变量 的初始化,构造函数体中的语句只能将其称为赋初值,而不能称作初始化。因为初始化只能初始 化一次,而构造函数体内可以多次赋值。
1.2、初始化列表
初始化列表:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式。构造函数都是有初始化列表的,都是可以使用初始化列表的。
例如:
class Date
{
public:Date(int year, int month, int day):_year(year),_month(month),_day(day){}
private:int _year;int _month;int _day;
};
1、每个成员变量在初始化列表中只能出现一次(初始化只能初始化一次)。
2、类中包含以下成员,必须放在初始化列表位置进行初始化:引用成员变量(因为引用也必须在定义的时候进行初始化),const成员变量(因为const修饰的变量必须在定义时初始化),自定义类型成员(且该类没有默认构造函数时)。
例如:
class A
{
public:A(int a):_a(a){}private:int _a;
};class B
{
public:B(int a, int ref):_aobj(a), _ref(ref), _n(10){}private:A _aobj; // 没有默认构造函数int& _ref; // 引用const int _n; // const
};
3、尽量使用初始化列表初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量, 一定会先使用初始化列表初始化。
注:尽量使用初始化列表进行初始化,因为不论如何都要走初始化列表,因为初始化列表是成员变量定义的地方。(不写初始化列表,初始化列表仍然存在)。当然不是所有的情况都能用初始化列表来进行初始化,只是对于能用初始化列表来初始化的就尽量用初始化列表来进行初始化。
例如:
class Time
{
public:Time(int hour = 0):_hour(hour){cout << "Time()" << endl;}private:int _hour;
};class Date
{
public:Date(int day){}private:int _day;Time _t;
};int main()
{Date d(1);return 0;
}
4、成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关
例如:
class A
{
public:A(int a):_a1(a),_a2(_a1){}void Print(){cout << _a1 << " " << _a2 << endl;}private:int _a2;int _a1;
};int main()
{A aa(1);aa.Print();return 0;
}
运行结果为:
1.3、explicit关键字
构造函数不仅可以构造与初始化对象,对于单个参数或者除第一个参数无默认值其余均有默认值 的构造函数,还具有类型转换的作用。
例如:
class Date
{
public://1. 单参构造函数,没有使用explicit修饰,具有类型转换作用//explicit修饰构造函数,禁止类型转换explicit Date(int year):_year(year){}/*//2. 虽然有多个参数,但是创建对象时后两个参数可以不传递,没有使用explicit修饰,具有类型转换作用//explicit修饰构造函数,禁止类型转换explicit Date(int year, int month = 1, int day = 1): _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(2022);// 用一个整形变量给日期类型对象赋值,实际编译器背后会用2023构造一个无名对象,最后用无名对象给d1对象进行赋值d1 = 2023;// 将1屏蔽掉,2放开时则编译失败,因为explicit修饰构造函数,禁止了单参构造函数类型转换的作用return 0;
}
如图:
用explicit修饰构造函数,将会禁止构造函数的隐式转换。上图中的两个临时变量都具有常性,即不变。
当自定义类型发生隐式类型转换时,C++对于自定义这种产生中间临时变量会进行优化,例如:构造+拷贝构造进行优化就变成了构造。也就是说,上图A aa1=1;这个隐式类型的转换,实际上会变成直接构造,省去了拷贝构造。
注:并不是所有的编译器都会进行优化,但是一般新的编译器都会优化。(关于拷贝对象时编译器的优化,具体将在下文展开。)
C++11中还出现了多参数构造函数也支持隐式类型转换,例如:
class Date
{
public:explicit Date(int year,int month,int _day=0)//若不使用explicit修饰则不会报错:_year(year),_month(month){}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(1,1);Date d2 = { 2,2 };return 0;
}
2、static成员
声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用 static修饰的成员函数,称之为静态成员函数。静态成员变量一定要在类外进行初始化。
例如:实现一个类,计算程序中创建出了多少个类对象。
class A
{
public:A() { ++_scount; }A(const A& t) { ++_scount; }~A() { --_scount; }static int GetACount() { return _scount; }private:static int _scount;//这里是声明
};int A::_scount = 0;int main()
{cout << A::GetACount() << endl;A a1, a2;A a3(a1);cout << A::GetACount() << endl;return 0;
}
1、静态成员变量为所有类对象所共享,不属于某个具体的对象,存放在全局区。
2、静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明。
3、类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问。
4、静态成员函数没有隐藏的this指针,不能访问任何非静态成员。
5、静态成员也是类的成员,受public、protected、private访问限定符的限制。
3、友元
友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,所以 友元不宜多用。
友元分为:友元函数和友元类
3.1、友元函数
问题:现在尝试去重载operator<<,然后发现没办法将operator<<重载成成员函数。因为cout的输出流对象和隐含的this指针在抢占第一个参数的位置。this指针默认是第一个参数也就是左操作数了。但是实际使用中cout需要是第一个形参对象,才能正常使用。所以要将operator<<重载成全局函数。但又会导致类外没办法访问成员,此时就需要友元来解决。operator>>同理。例如:
class Date
{
public:Date(int year, int month, int day):_year(year),_month(month),_day(day){}// d1 << cout; -> d1.operator<<(&d1, cout); 不符合常规调用// 因为成员函数第一个参数一定是隐藏的this,所以d1必须放在<<的左侧ostream& operator<<(ostream& _cout){_cout << _year << "-" << _month << "-" << _day << endl;return _cout;}private:int _year;int _month;int _day;
};int main()
{Date d1(1, 1, 1);d1 << cout;return 0;
}
向上面这种写法肯定是很奇怪的,所以需要用友元来解决。
友元函数可以直接访问类的私有成员,它是定义在类外部的普通函数,不属于任何类,但需要在 类的内部声明,声明时需要加friend关键字。例如:
class Date
{friend ostream& operator<<(ostream& _cout, const Date& d);friend istream& operator>>(istream& _cin, Date& d);public:Date(int year = 1900, int month = 1, int day = 1): _year(year), _month(month), _day(day){}private:int _year;int _month;int _day;
};
ostream& operator<<(ostream& _cout, const Date& d)
{_cout << d._year << "-" << d._month << "-" << d._day;return _cout;
}
istream& operator>>(istream& _cin, Date& d)
{_cin >> d._year;_cin >> d._month;_cin >> d._day;return _cin;
}
int main()
{Date d;cin >> d;cout << d << endl;return 0;
}
注意: 友元函数可访问类的私有和保护成员,但不是类的成员函数。友元函数不能用const修饰。友元函数可以在类定义的任何地方声明,不受类访问限定符限制。一个函数可以是多个类的友元函数。 友元函数的调用与普通函数的调用原理相同。
3.2、友元类
友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。友元关系是单向的,不具有交换性。比如:下面的Time类和Date类,在Time类中声明Date类为其友元类,那么可以在Date类中直接访问Time类的私有成员变量,但想在Time类中访问Date类中私有的成员变量则不行。
友元关系不能传递。比如:如果C是B的友元,B是A的友元,则不能说明C是A的友元。
友元关系不能继承(关于继承后面再讲)。
例如:
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;
};
4、内部类
如果一个类定义在另一个类的内部,这个内部类就叫做内部类。内部类是一个独立的类, 它不属于外部类,更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任何优越的访问权限。
注意:内部类就是外部类的友元类,内部类可以通过外部类的对象参数来访问外部类中的所有成员。但是外部类不是内部类的友元。
特性:
1、内部类可以定义在外部类的public、protected、private都是可以的,定义是可以的,但是仍然会受到访问限定符的限制。
2、内部类可以直接访问外部类中的static成员,不需要外部类的对象或类名。
3、sizeof(外部类)=外部类,和内部类没有任何关系;内部类是独立的,只是受外部类类域的限制并且受访问限定符的限制。
例如:
class A
{
public:class B // B天生就是A的友元{public:void foo(const A& a){cout << k << endl;//OKcout << a.h << endl;//OK}};private:static int k;int h;
};int A::k = 1;int main()
{A::B b;//若想定义B类这样才行。b.foo(A());return 0;
}
5、匿名对象
匿名对象的特点,生命周期只有一行,具有常性。
const引用会延长匿名对象的生命周期,本质上相当于匿名对象有名字了。例如:
const A& ref = A();
当ref出作用域后,匿名对象也就销毁了。
例如:
class A
{
public:A(int a = 0):_a(a){cout << "A(int a)" << endl;}~A(){cout << "~A()" << endl;}private:int _a;
};class Solution
{
public:int Sum_Solution(int n) {//...return n;}
};int main()
{A aa1;// 匿名对象的特点不用取名字,但是他的生命周期只有这一行,我们可以看到下一行他就会自动调用析构函数。A();A aa2(2);// 匿名对象在这样场景下就很好用,当然还有一些其他使用场景,这个我们以后遇到了再说。Solution().Sum_Solution(10);//也就是说匿名对象对于即用即销毁的情况下比较方便。return 0;
}
6、拷贝对象时的优化(了解)
在传参和传返回值的过程中,一般编译器会做一些优化,减少对象的拷贝,这个在一些场景下还 是非常有用的。
例如:连续的构造或者拷贝构造会被编译器优化
class A
{
public:A(int a = 0):_a(a){cout << "A(int a)" << endl;}A(const A& aa):_a(aa._a){cout << "A(const A& aa)" << endl;}A& operator=(const A& aa){cout << "A& operator=(const A& aa)" << endl;if (this != &aa){_a = aa._a;}return *this;}~A(){cout << "~A()" << endl;}void Print(){cout << "Print()->" << _a << endl;}private:int _a;};
void f1(A aa)
{aa.Print();
}int main()
{A aa1;f1(aa1);cout << "--------------------------------" << endl;f1(A(1));//优化为了直接构造cout << "--------------------------------" << endl;f1(1);//优化为了直接构造。cout << "--------------------------------" << endl;A aa2 = 1;//优化为了直接构造cout << "--------------------------------" << endl;A aa3 = A(2);//优化为了直接构造return 0;
}
例如:
class A
{
public:A(int a = 0):_a(a){cout << "A(int a)" << endl;}A(const A& aa):_a(aa._a){cout << "A(const A& aa)" << endl;}A& operator=(const A& aa){cout << "A& operator=(const A& aa)" << endl;if (this != &aa){_a = aa._a;}return *this;}~A(){cout << "~A()" << endl;}void Print(){cout << "Print()->" << _a << endl;}private:int _a;
};A f2()
{A aa;return aa;
}int main()
{A ret1=f2();//优化为了直接构造cout << "---------------------------" << endl;A ret2;ret2 = f2();//只优化了一次拷贝构造return 0;
}
例如:
class A
{
public:A(int a = 0):_a(a){cout << "A(int a)" << endl;}A(const A& aa):_a(aa._a){cout << "A(const A& aa)" << endl;}A& operator=(const A& aa){cout << "A& operator=(const A& aa)" << endl;if (this != &aa){_a = aa._a;}return *this;}~A(){cout << "~A()" << endl;}void Print(){cout << "Print()->" << _a << endl;}private:int _a;
};A f2()
{return A(1);
}A f3()
{return 1;
}int main()
{A ret1=f2();//优化为了直接构造cout << "----------------------" << endl;A ret2 = f3();//优化为了直接构造return 0;
}
注意:这一块的优化取决与编译器,不同的编译器优化的情况是不同的。
7、重新理解类与对象
现实生活中的实体计算机并不认识,计算机只认识二进制格式的数据。如果想要让计算机认识现 实生活中的实体,用户必须通过某种面向对象的语言,对实体进行描述,然后通过编写程序,创 建对象后计算机才可以认识。
比如想要让计算机认识洗衣机,就需要:
1、用户先要对现实中洗衣机实体进行抽象---即在人为思想层面对洗衣机进行认识,洗衣机有什么属性,有那些功能,即对洗衣机进行抽象认知的一个过程。
2、经过1之后,在人的头脑中已经对洗衣机有了一个清醒的认识,只不过此时计算机还不清楚,想要让计算机识别人想象中的洗衣机,就需要人通过某种面相对象的语言(比如:C++、 Java、Python等)将洗衣机用类来进行描述,并输入到计算机中。
3、经过2之后,在计算机中就有了一个洗衣机类,但是洗衣机类只是站在计算机的角度对洗衣机对象进行描述的,通过洗衣机类,可以实例化出一个个具体的洗衣机对象,此时计算机才能知道洗衣机是什么东西。
4、用户就可以借助计算机中洗衣机对象,来模拟现实中的洗衣机实体了。
在类和对象阶段,一定要体会到,类是对某一类实体(对象)来进行描述的,描述该对象具有哪些属性,哪些方法,描述完成后就形成了一种新的自定义类型,才用该自定义类型就可以实例化具体的对象。在面向对象这一块,更多关注的是类与类之间的关系。
8、日期类的实现
日期类的实现,作为类的练习。
Date.h
#include<iostream>
using namespace std;
#include<assert.h>class Date
{//友元;有了友元就可以让这个函数访问类的私有属性。friend ostream& operator<<(ostream& out, const Date& d);friend istream& operator>>(istream& in, Date& d);public:Date(int year = 1900, int month = 1, int day = 1);//构造函数void Print() const;int GetMonthDay(int year, int month) const;//运算符重载bool operator==(const Date& d) const;bool operator!=(const Date& d) const;bool operator<(const Date& d) const;bool operator<=(const Date& d) const;bool operator>(const Date& d) const;bool operator>=(const Date& d) const;Date& operator+=(int day);Date operator+(int day) const;Date& operator-=(int day);Date operator-(int day) const;int operator-(const Date& d) const;//跟上面的-构成重载了。Date& operator++();Date operator++(int);Date& operator--();Date operator--(int);/*void operator<<(ostream& out);*/private:int _year;int _month;int _day;
};ostream& operator<<(ostream& out, const Date& d);istream& operator>>(istream& in, Date& d);
Date.cpp
#include"Date.h"int Date::GetMonthDay(int year, int month) const
{assert(month >= 0 && month < 13);int monthday[13] = { 0,31,28,31,30,31,30,31,31,30,31,30,31 };if (month == 2 && (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)){return 29;}else{return monthday[month];}
}Date::Date(int year, int month, int day)
{if (month > 0 && month < 13 && (day > 0 && day <= GetMonthDay(year, month))){_year = year;_month = month;_day = day;}else{cout << "日期非法" << endl;}
}void Date::Print() const
{cout<<_year<<'/'<<_month<<'/'<<_day<<endl;
}bool Date::operator==(const Date& d) const
{return _year == d._year&& _month == d._month&& _day == d._day;
}bool Date::operator<(const Date& d) const
{return _year < d._year|| (_year == d._year && _month < d._month)|| (_year == d._year && _month == d._month && _day < d._day);
}bool Date::operator<=(const Date& d) const
{return *this < d || *this == d;//利用了上面两个运算符重载。
}bool Date::operator>(const Date& d) const
{return !(*this <= d);
}bool Date::operator>=(const Date& d) const
{return !(*this < d);
}bool Date::operator!=(const Date& d) const
{return !(*this == d);
}Date& Date::operator+=(int day)//出作用域this还在,可以用引用返回
{if (day < 0){*this -= -day;return *this;}_day += day;while (_day > GetMonthDay(_year, _month)){_day -= GetMonthDay(_year, _month);_month++;if (_month == 13){++_year;_month = 1;}}return *this;
}Date Date::operator+(int day) const//出了作用域tmp不在,所以不可以使用引用返回。
{Date tmp(*this);tmp += day;return tmp;
}Date& Date::operator-=(int day)
{if (day < 0){*this += -day;return *this;}_day -= day;while (_day <= 0){--_month;if (_month == 0){--_year;_month = 12;}_day += GetMonthDay(_year, _month);}return *this;
}Date Date::operator-(int day) const
{Date tmp(*this);tmp -= day;return tmp;
}//在自定义类型这一块,前置++的效率要高于后置++
//在内置类型这一块前置和后置没有区别。
Date& Date::operator++()
{*this += 1;return *this;
}Date Date::operator++(int)
{Date tmp(*this);*this += 1;return tmp;
}Date& Date::operator--()
{*this -= 1;return *this;
}Date Date::operator--(int)
{Date tmp(*this);*this -= 1;return tmp;
}int Date::operator-(const Date& d) const
{Date max = *this;Date min = d;int flag = 1;if (*this < d){max = d;min = *this;flag = -1;}int n = 0;while (min != max){++min;++n;}return n * flag;
}//返回值是为了支持连续输入和输出。
ostream& operator<<(ostream& out, const Date& d)//这里不一定非要使用友元,也可以在类里面写一些能得到私有属性的函数,从而得到私有属性。
{out << d._year << "年" << d._month << "月" << d._day << "日" << endl;return out;
}istream& operator>>(istream& in, Date& d)
{in >> d._year >> d._month >> d._day;return in;
}
9、练习题
9.1、第一题
链接:求1+2+3+...+n
参考:
class Sum
{
public:Sum(){_sum += _i;_i++;}static int GetSum(){return _sum;}
private:static int _i;static int _sum;
};int Sum::_i = 1;
int Sum::_sum = 0;class Solution {
public:int Sum_Solution(int n) {Sum a[n];return Sum::GetSum();}
};
9.2、第二题
链接:计算日期到天数的转换
9.3、第三题
链接:日期差值
9.4、第四题
链接:打印日期
9.5、第五题
链接:日期累加
相关文章:
第四讲:类与对象(下)
目录 1、再谈构造函数 1.1、构造函数体赋值 1.2、初始化列表 1.3、explicit关键字 2、static成员 3、友元 3.1、友元函数 3.2、友元类 4、内部类 5、匿名对象 6、拷贝对象时的优化(了解) 7、重新理解类与对象 8、日期类的实现 9、练习题 9…...
ReAct 框架 | 提示词工程(1)
ReAct 框架 1、什么是 ReAct 框架?2、基于 ReAct 框架的提示词3、结合 LangChain 框架使用4、总结 1、什么是 ReAct 框架? ReAct : Reasoning Acting ,将推理与外部工具调用结合,通过交互式探索解决复杂问题。 优点…...
第一部分——Docker篇 第一章 Docker容器
关于系统的改造探索 开篇:系统改造的调研报告 第一部分——Docker篇 第一章 Docker容器 第二章 Docker安装 第三章 构建自定义镜像 第四章 搭建镜像仓库 第五章 容器编排 第六章 容器监控 文章目录 关于系统的改造探索第一部分——Docker篇 前言一、就是你了——…...
ubuntu,react的学习(1)
在此目录下,开启命令行 /home/kt/react 如下操作 tkt4028:~/react$ npm create vitelatest task-manager -- --template react Need to install the following packages: create-vite6.3.1 Ok to proceed? (y) y> npx > cva task-manager --template react…...
AR 赋能儿童娱乐:剧本杀与寻宝小程序搭建秘籍
在科技飞速发展的当下,儿童娱乐领域正经历着一场创新变革。AR(增强现实)技术的融入,为儿童剧本杀与寻宝游戏带来了前所未有的沉浸式体验。通过搭建专属小程序,孩子们能够在虚拟与现实交织的世界中开启奇幻冒险。接下来…...
2017年-全国大学生数学建模竞赛(CUMCM)试题速浏、分类及浅析
2017年-全国大学生数学建模竞赛(CUMCM)试题速浏、分类及浅析 全国大学生数学建模竞赛(China Undergraduate Mathematical Contest in Modeling)是国家教委高教司和中国工业与应用数学学会共同主办的面向全国大学生的群众性科技活动,目的在于激励学生学习数学的积极性,提高学…...
密码学基础——分组密码的运行模式
前面的文章中文我们已经知道了分组密码是一种对称密钥密码体制,其工作原理可以概括为将明文消息分割成固定长度的分组,然后对每个分组分别进行加密处理。 下面介绍分组密码的运行模式 1.电码本模式(ECB) 2.密码分组链接模式&…...
zk源码—2.通信协议和客户端原理一
大纲 1.ZooKeeper如何进行序列化 2.深入分析Jute的底层实现原理 3.ZooKeeper的网络通信协议详解 4.客户端的核心组件和初始化过程 5.客户端核心组件HostProvider 6.客户端核心组件ClientCnxn 7.客户端工作原理之会话创建过程 1.ZooKeeper如何进行序列化 (1)什么是序列化…...
【NLP】Transformer网络结构(2)
一、Transformer 整体架构 Transformer 由 Encoder 和 Decoder 堆叠组成,每个 Encoder/Decoder 层包含以下核心模块: Encoder 层:Multi-Head Self-Attention → Add & LayerNorm → Feed-Forward → Add & LayerNormDecoder 层&…...
【LeetCode77】组合
题目描述 给定区间 [1, n] 和一个整数 k,需要返回所有可能的 k 个数的组合。 思路 算法选择:回溯算法 回溯算法是一种试探性搜索方法,非常适合用来解决组合问题。基本思想是: 从数字 1 开始,逐步构建组合。当当前组…...
1631. 最小体力消耗路径
文章目录 题意思路代码 题意 题目链接 思路 搜索 代码 class Solution { public:int minimumEffortPath(vector<vector<int>>& heights) {int m heights.size();int n heights[0].size();int x_add[] {0, 0, 1, -1};int y_add[] {1, -1, 0, 0};if (m …...
时间复杂度和空间复杂度
🌟 各位看官好,我是maomi_9526! 🌍 种一棵树最好是十年前,其次是现在! 🚀 今天来学习C语言的相关知识。 👍 如果觉得这篇文章有帮助,欢迎您一键三连,分享给更…...
Python基于OpenCV和SVM实现中文车牌识别系统GUI界面
说明:这是一个系统实战项目,如需项目代码可以直接到文章最后关注获取。 项目背景 随着智能交通系统和智慧城市的发展,车牌识别技术在车辆管理、交通监控、停车场收费等领域发挥着重要作用。传统的车牌识别系统主要针对英文和数字的识别&…...
用AbortController取消事件绑定
视频教程 React - 🤔 Abort Controller 到底是什么神仙玩意?看完这个视频你就明白了!💡_哔哩哔哩_bilibili AbortController的好处之一是事件绑定的函数已无需具名函数,匿名函数也可以被取消事件绑定了 //该代码2秒后点击失效…...
4月7日随笔
晚饭塔斯汀 下了晚自习买了一瓶百香果rio 还有一块五毛钱的老酸奶,这个糖吃的时候是真开心呀 英语课互动感觉越来越少了,我甚至看了十分钟的小排球 解析几何和微积分都听不进去了。就算坐在第三排还是会走神。但是不知道为什么我刷视频和打游戏的时…...
Android使用声网SDK实现音视频互动(RTC)功能
一、前期准备 1、注册声网账号 声网官网 2、创建项目 拿到AppID,主要证书 二、代码部分 先上一下官方提供的demo地址: Agora-RTC-QuickStart: 此仓库包含 Agora RTC Native SDK 的QuickStart示例项目。 - Gitee.comhttps://gitee.com/agoraio-comm…...
【go】slice的浅拷贝和深拷贝
浅拷贝(Shallow Copy) 浅拷贝是指只复制切片本身的结构(指针、长度和容量),而不复制底层数组的元素。 实现方式 直接赋值: slice1 : []int{1, 2, 3} slice2 : slice1 // 浅拷贝切片操作: slice1 : []int{1, 2, 3} s…...
哑铃图:让数据对比一目了然【Dumbbell Chart】
没错,当我祭出 “哑铃” 阵列,你当如何破解,哈哈哈哈…此时,你可以适当怀疑笔者的精神状态了。但话说回来,如果稍加想象,把上图竖起来,“大致” 就是我要分享的 “哑铃图” 了。😑 …...
Spring Boot 集成 MongoDB 时自动创建的核心 Bean 的详细说明及表格总结
以下是 Spring Boot 集成 MongoDB 时自动创建的核心 Bean 的详细说明及表格总结: 核心 Bean 列表及详细说明 1. MongoClient 类型:com.mongodb.client.MongoClient作用: MongoDB 客户端核心接口,负责与 MongoDB 服务器建立连接、…...
水产养殖水下监控无人机推荐-P200PRO
水产养殖水下监控无人机推荐 | 潜 鲛 P200 PRO:您的“水下管家”,养鱼增产、降本增效的终极利器! ——上海 棕航电子 科技,用技术守护每一方鱼塘 一、水产养殖的痛点:看不见的水下,才是赚钱的关键 …...
数据结构与算法-数学-基础数学算法(筛质数,最大公约数,最小公倍数,质因数算法,快速幂,乘法逆元,欧拉函数)
一:筛质数: 1-埃氏筛法 该算法核心是从 2 开始,把每个质数的倍数标记为合数,时间复杂度约为 O(nloglogn)。 #include <iostream> #include <vector>u sing namespace std; const int N 1000010; bool st[N]; …...
elasticSearch-搜索引擎
搜索引擎的优势 有了数据库分页查询,为什么还需要搜索引擎? 搜索引擎速度上很快数据库分页查询,随着数据库数据量增大,页数靠后,会导致搜索速度变慢,但是搜索引擎不会搜索引擎支持分词查询,地…...
MQTT-Dashboard-数据集成
sink [sɪŋk] 下沉;沉没;沉降;...
uni-app项目运行在浏览器、微信开发者工具、mumu模拟器
一、安装HBuilder X 1、下载HBuilder X 官网网址:https://dcloud.io/hbuilderx.html 根据电脑系统下载对应的版本(我的电脑是Windows 10) 2.安装HBuilder X 直接将HBuilderX.4.61.2025040322-alpha.zip解压到自己想要存放的文件夹中 双击…...
从零开始微调Embedding模型:基于BERT的实战教程
文章目录 背景微调实战装包介绍 项目文件介绍微调硬件配置要求 debug 重要代码分析【选看】资源分享参考资料 背景 在理解与学会了Naive RAG的框架流程后,就很自然地关注到embedding模型,与问题相关的文本召回,也有很多论文在做这方面的创新…...
机器学习(神经网络基础篇)——个人理解篇5(梯度下降中遇到的问题)
在神经网络训练中,计算参数的梯度是关键步骤。numerical_gradient 方法旨在通过数值微分(中心差分法)计算损失函数对网络参数的梯度。然而,该方法的实现存在一个关键问题,导致梯度计算错误。 1、错误代码示例…...
带label的3D饼图(threejs)
3D饼图 使用three.js实现,选择threejs的原因:label需要实际的显示在具体的饼对应的模块上 “three”: “^0.127.0”, <template><div><div ref"chartContainer" class"chart-container"></div><div clas…...
ragflow开启https访问:使用自签证书还是有不安全警告,如何解决
背景:在ragflow里的使用了自签证书来启动ragflow,在浏览器里访问还是不安全警告,如何解决 在方案2中,证书不会在访问网站时自动下载,需要你手动获取并安装证书文件。以下是具体操作步骤: 详细步骤:手动获取并安装自签名证书 第一步:获取证书文件 找到证书文件 证书文件位…...
条件变量核心要素
条件变量内部实现原理 原子性解锁阻塞机制: // pthread_cond_wait内部伪代码大致如下: int pthread_cond_wait(cond_t *cond, mutex_t *mutex) {atomic {unlock(mutex); // 原子操作中先释放互斥锁block_thread(); // 立即将线程加入等待队列…...
C语言求鞍点
我们先在第一行中找出最大的值,然后在该列中找出最小值看这两个是否相等。 若是相等,那么这个数就是鞍点跳出循环 若是不想等,则继续在下一行寻找,若是一直到整体的循环都结束了还是没有,那么不存在鞍点。 运行结果:…...
XELA机器人多种“形态和玩法”的Uskin磁性阵列式三轴触觉传感器,你使用过了吗?
XELA Robotics为机器人行业提供创新的磁性触觉传感技术,uSkin触觉传感器是一种高密度的三轴触觉传感器,因其轻薄、表面柔软耐用和布线少的结构设计,可以轻松集成到机器人本体,灵巧手,机器人夹爪等部位,使机…...
转换效率高达 96%,12V转5V同步降压WD5030
特点1 宽输入电压范围:能在 7V 至 30V 的宽输入电压范围内工作,可适应多种不同电压等级的供电环境,无论是工业设备中的较高电压输入,还是便携式设备经过初步升压后的电压,都能良好适配,极大地拓展了应用的…...
请你回答一下单元测试、集成测试、系统测试、验收测试、回归测试这几步中最重要的是哪一步?
在软件测试的不同阶段中,每个环节都有其不可替代的价值,但若从工程效率和缺陷防控的全局视角来看,单元测试(Unit Testing) 是质量金字塔的基石,其重要性最为关键。以下是分层解析: 一、从缺陷修复成本看优先级 美国国家标准与技术研究院(NIST)研究显示: 单元测试阶段…...
QML和C++交互
目录 1 QML与C交互基础1.1 全局属性1.2 属性私有化(提供接口访问) 2 QT与C交互(C创建自定义对象,qml文件直接访问)3 QT与C交互(qml直接访问C中的函数)4 QT与C交互(qml端发送信号 C端实现槽函数)…...
2021年-全国大学生数学建模竞赛(CUMCM)试题速浏、分类及浅析
2021年-全国大学生数学建模竞赛(CUMCM)试题速浏、分类及浅析 全国大学生数学建模竞赛(China Undergraduate Mathematical Contest in Modeling)是国家教委高教司和中国工业与应用数学学会共同主办的面向全国大学生的群众性科技活动,目的在于激励学生学习数学的积极性,提高学…...
mariadb使用docker compose方式安装
问题 本地mac m1上面的mysql和mariadb突然不用使用了,重新安装也不想,最近mac系统也更新了,brew也更新了,重新安装mariadb还是不能正常使用,现在我打算使用docker来安装本地的mariadb了。 默认配置文件my.cnf 从容器…...
Logo语言的死锁
Logo语言的死锁现象研究 引言 在计算机科学中,死锁是一个重要的研究课题,尤其是在并发编程中。它指的是两个或多个进程因争夺资源而造成的一种永久等待状态。在编程语言的设计与实现中,如何避免死锁成为了优化系统性能和提高程序可靠性的关…...
具身智能零碎知识点(一):深入解析Transformer位置编码
深入解析Transformer位置编码 Transformer位置编码完全解析:从公式到计算的终极指南一、位置编码的必要性演示二、位置编码公式深度拆解原始公式参数说明(以d_model4为例) 三、完整计算过程演示步骤1:计算频率因子步骤2࿱…...
0201概述-机器学习-人工智能
文章目录 1、概述1.1、示例1.2、概念 2、应用场景2.1、行业应用场景2.1.1、金融领域2.1.2、 医疗健康2.1.3、零售与电商2.1.4、 制造业2.1.5、自动驾驶 2.2、功能场景分类2.2.1、 预测类2.2.2、分类与识别类2.2.3、生成与优化类 2.3、机器学习适用场景的共同特征 3、实现机器学…...
金能电力工具柜:“五世同堂”演绎创新华章
在电力与工业领域的浩瀚星空中,金能电力如同一颗璀璨的星辰,其工具柜产品更是经历了五代更迭,如同家族中的“五世同堂”,每一代都承载着前人的智慧与后人的创新,共同谱写着传承与创新的交响曲。 初识平凡:普…...
蓝桥杯每日刷题c++
目录 P9240 [蓝桥杯 2023 省 B] 冶炼金属 - 洛谷 (luogu.com.cn) P8748 [蓝桥杯 2021 省 B] 时间显示 - 洛谷 (luogu.com.cn) P10900 [蓝桥杯 2024 省 C] 数字诗意 - 洛谷 (luogu.com.cn) P10424 [蓝桥杯 2024 省 B] 好数 - 洛谷 (luogu.com.cn) P8754 [蓝桥杯 2021 省 AB2…...
MySQL基础 [五] - 表的增删查改
目录 Create(insert) Retrieve(select) where条件 编辑 NULL的查询 结果排序(order by) 筛选分页结果 (limit) Update Delete 删除表 截断表(truncate) 插入查询结果(insertselect&…...
深入解析 MySQL 中的日期时间函数:DATE_FORMAT 与时间查询优化
深入解析 MySQL 中的日期时间函数:DATE_FORMAT 与时间查询优化 在数据库管理和应用开发中,日期和时间的处理是不可或缺的一部分。MySQL 提供了多种日期和时间函数来满足不同的需求,其中DATE_FORMAT函数以其强大的日期格式化能力,…...
GPU是什么? 与 FPGA 有何关联
前段时间,AMD 和英伟达相继接到通知将对我国断供高端 GPU 芯片,很多人这才意识到 GPU 的战略价值。那么 GPU 究竟是什么?它为何如此重要?今天就由 宸极教育 带大家一起了解 GPU 的核心地位,以及它与国产FPGA发展的关系…...
数据结构与算法:基础与进阶
🌟 各位看官好,我是maomi_9526! 🌍 种一棵树最好是十年前,其次是现在! 🚀 今天来学习C语言的相关知识。 👍 如果觉得这篇文章有帮助,欢迎您一键三连,分享给更…...
低配置云服务器网站的高效防御攻略
在网络环境日益复杂的当下,低配置云服务器网站常面临攻击威胁。不少站长疑惑,明明设置了 CC 防御,服务器却依旧不堪一击,这是怎么回事呢? 比如,在 CC 防御配置中,设定 10 秒内允许访问 50 次。但…...
使用 Lua 脚本高效查询 Redis 键的内存占用
使用 Lua 脚本高效查询 Redis 键的内存占用 在处理 Redis 数据时,我们常常需要了解某些键的内存占用情况,尤其是在优化内存使用或排查问题时。虽然 Redis 提供了MEMORY USAGE命令来查询单个键的内存占用,但如果需要批量查询多个键࿰…...
【Linux篇】基础IO - 揭秘重定向与缓冲区的管理机制
📌 个人主页: 孙同学_ 🔧 文章专栏:Liunx 💡 关注我,分享经验,助你少走弯路! 文章目录 一. 理解重定向1.1 理解重定向1.2 dup21.3 进一步理解重定向输出重定向:追加重定向…...
centos 8 启动Elasticsearch的时候报内存不足问题解决办法
centos 8 启动Elasticsearch 的时候报错,导致无法启动Elasticsearch 。 [root@CentOS-8 ~]# journalctl -xe Apr 07 18:25:56 CentOS-8.0 kernel: [ 8754] 0 8754 3180 63 69632 0 0 sh Apr 07 18:25:56 CentOS-8.0 kernel: [ 8755] 0 8755 3180 64 69632 0 0 sh Apr 07 18:25…...
深入剖析Java IO设计模式:从底层原理到实战应用
🔍 引言:设计模式与IO的完美交响 在软件开发的浩瀚星河中,设计模式犹如璀璨的导航星,而Java IO体系则是支撑数据流动的神经网络。 当我们以设计模式的视角重新审视Java IO库时,会发现这个看似平凡的IO世界实则暗藏着…...