类和对象|六个默认成员函数|const成员函数|运算符重载
文章目录
- 默认成员构造函数
- 1. 构造函数
- 1.1 概念
- 1.2 特性
- 2. 析构函数
- 2.1 概念
- 2.2 特性
- 3. 拷贝构造函数
- 3.1 概念
- 3.2 特性
- 4. 运算符重载
- 4.1 赋值重载
- 4.2 自增自减重载
- 4.3 取地址操作符重载
- 5. const成员函数
- 6. 取地址重载
默认成员构造函数
上一节我们说过,空类的大小是1字节用来占位,那空类是不是真的什么都没有呢?
并不是,C++中的任何一个类都具有6个默认成员函数
即使它是空类,它也拥有这6个默认成员函数,下面我们依次介绍这些默认成员函数~
1. 构造函数
1.1 概念
构造函数是当对象定义时编译器默认调用的,用来完成对对象属性初始化的工作。
我们一开始写的
class Date是这样class Date {private:int _year;int _month;int _day;public:void Init(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout << _year << " " << _month << " " << _day << endl;} };int main() {Date d1,d2;d1.Init(2023, 7, 21);d2.Init(2023, 7, 22);d1.Print();d2.Print(); }每定义一个对象都需要调用初始化函数初始化对象的属性,如果我们哪一次忘记了初始化,那么再访问该属性时便会访问随机值,因此有没有一种办法定义对象时直接初始化呢?这样就我们就不会忘记初始化了
我们可以定义构造函数帮我们完成这件事:
构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,以保证每个数据成员都有 一个合适的初始值,并且在对象整个生命周期内只调用一次。
1.2 特性
构造函数是特殊的成员函数,需要注意的是,构造函数虽然名称叫构造,但是构造函数的主要任务并不是开空间创建对象,而是初始化对象。
特征如下
- 函数名与类名相同
- 无返回值类型
- 对象实例化时编译器自动调用对应的构造函数
- 构造函数可以重载(本质就是我们可以写多个构造函数,提供多种初始化方式)
class Date的构造函数class Date {private:int _year;int _month;int _day;public:Date(){_year = 1;_month = 1;_day = 1;}void Init(int year, int month, int day){_year = year;_month = month;_day = day;}void Print(){cout << _year << " " << _month << " " << _day << endl;} };int main() {Date d1;d1.Print(); }运行结果:
构造函数在对象创建的时候自动调用(对象是编译器创建的,不是构造函数创建的,构造函数只负责对创建对象的属性进行初始化操作)
带参数的构造函数//带参数的构造函数 Date(int year, int month, int day) {_year = year;_month = month;_day = day; } int main() {Date d1;//调用无参构造函数Date d2(2023, 7, 21);//想要调用带参数的构造函数必须将括号写在对象名后面而不是类名后面d1.Print();d2.Print();// 注意:如果通过无参构造函数创建对象时,对象后面不用跟括号,否则就成了函数声明// 以下代码的函数:声明了d3函数,该函数无参,返回一个日期类型的对象// warning C4930: “Date d3(void)”: 未调用原型函数(是否是有意用变量定义的?)Date d3(); }**注意:**语法规定:调用带参数的构造函数必须将括号写在对象名后面
将带参构造函数和不带参构造函数合并为全缺省构造函数//全缺省构造函数Date(int year = 1, int month = 1, int day = 1){_year = year;_month = month;_day = day;}运行结果:
若定义了全缺省构造函数,也定义了无参构造函数,调用对象时没有指定构造函数的参数编译器不知道调用哪一个构造函数(全缺省还是无参),因而会报错(报错仅仅是因为编译器不知道调用哪一个而不是语法错误)
class Stackclass Stack { private:int* _a;int _top;int _capacity; public://带缺省参数的构造函数Stack(int capacity = 4){_capacity = capacity;_top = 0;_a = (int*)malloc(sizeof(int) * _capacity);assert(_a);}void Push(int val){if (_capacity == _top){_capacity *= 2;int* tmp = (int*)realloc(_a, sizeof(int) * _capacity);if (tmp)_a = tmp;}_a[_top] = val;_top++;}int& Top(){return _a[_top - 1];}void Pop(){assert(_top > 0);_top--;} };int main() {Stack st;st.Push(1);st.Push(2);st.Push(3);st.Push(4);st.Push(5);cout << st.Top() << endl;st.Pop();cout << st.Top() << endl; }
运行结果:
`通过汇编观察定义对象时调用了构造函数
使用了构造函数可以让我们省去和C语言一样手动初始化栈,并且使用默认参数可以让我们设定初始容量,例如我们事先知道栈中要插入1000个元素,我们就可以直接这么定义栈
Stack st(1000);这省去了后续扩容的消耗。
-
如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数(后面皆称为系统默认构造函数),一旦用户显式定义编译器将不再生成。
class Dateclass Date { public:/*// 如果用户显式定义了构造函数,编译器将不再生成Date(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类中构造函数屏蔽后,代码可以通过编译,因为编译器生成了一个无参的默认构造函数// 将Date类中构造函数放开,代码编译失败,因为一旦显式定义任何构造函数,编译器将不再生成// 无参构造函数,放开后报错:error C2512: “Date”: 没有合适的默认构造函数可用Date d1;d1.Print();return 0; }我们没有定义构造函数,因此定义d1时编译器会调用编译器生成的
默认构造函数打印结果
-
系统默认构造函数作用:
-
系统默认构造函数对类的内置类型不做处理(语言自带的类型),有些编译器可能会进行处理,但是C++标准并没有这么规定
-
系统默认构造函数会去调用自定义类型变量的构造函数(union,struct,class等)
class Dateclass 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; }; int main() {Date d;//调用Date类的系统默认构造函数return 0; }运行结果:<


解释:
Date类定义对象时我们会自动调用Date类的系统默认构造函数,系统默认构造函数对Date类的内置类型不做处理,调用自定义类型Time默认构造函数,因此_t的_hour,_minute,_second都会被初始化为0.来看一段问题代码class Time { public:Time(int hour, int minute, int second){cout << "Time()" << endl;_hour = hour;_minute = minute;_second = second;} private:int _hour;int _minute;int _second; }; class Date { private:// 基本类型(内置类型)int _year;int _month;int _day;// 自定义类型Time _t; }; int main() {Date d;//调用Date类的系统默认构造函数return 0; }运行结果:

**解释:**Date只有系统默认构造函数,定义对象时调用系统默认构造函数,系统默认构造函数调用
Time类的默认构造函数,但是我们已经定义了Time带参数的构造函数,因此Time类不具有默认构造函数,因而程序出错。注意:C++11针对系统默认构造函数不会对内置类型进行处理做了一个补丁,C++11后允许将内置成员变量在类中声明时给定默认值
//C++11给定缺省值 class A { public:void Print(){cout << _a << " " << _c << endl;} private:int _a = 1;char _c = 'a'; };int main() {A a;//调用系统默认构造函数给_a初值1,_c初值'a'a.Print();return 0; }-
调用时可以不传参的构造函数称为默认构造函数,默认构造函数有3类:系统默认构造函数,自定义的无参构造函数,全缺省的构造函数。
//默认构造函数 class A {public://自定义无参构造函数A(){cout << "A()\n";}//全缺省构造函数A(int a = 1, int b = 2){_a = a;_b = b;cout << "A(int a, int b)\n";} private:int _a;int _b; };int main() {A a;//无法编译通过,因为不知道调用哪一个默认构造函数return 0; }
-
-
-
2. 析构函数
2.1 概念
析构函数与构造函数的功能相反。**析构函数的作用是在对象销毁前后执行对象中资源清理工作(**对象销毁不是析构函数完成的就像对象的创建不是构造函数完成的一样)
2.2 特性
- 析构函数名是在类名前加上字符
~。 - 无参数无返回值类型。
- 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构
函数不能重载
-
对象生命周期结束时,C++编译系统系统自动调用析构函数
class Stack
typedef int DataType;
class Stack
{
public:Stack(size_t capacity = 3){_array = (DataType*)malloc(sizeof(DataType) * capacity);if (NULL == _array){perror("malloc申请空间失败!!!");return;}_capacity = capacity;_size = 0;}void Push(DataType data){// CheckCapacity();_array[_size] = data;_size++;}// 其他方法...~Stack(){if (_array){free(_array);_array = NULL;_capacity = 0;_size = 0;}}
private:DataType* _array;int _capacity;int _size;
};
void TestStack()
{Stack s;s.Push(1);s.Push(2);
}
有了析构函数就不需要我们自己手动销毁栈了
-
编译器生成的默认析构函数作用
- 对于内置类型不做处理
- 对于自定义类型成员,调用自定义类型的析构函数
class Time { public:Time(){cout << "Time()" << endl;}~Time(){cout << "~Time()" << endl;} private:int _hour;int _minute;int _second; }; class Date { public:Date(){cout << "Date()" << endl;}~Date(){cout << "~Date()" << endl;} private:// 基本类型(内置类型)int _year = 1970;int _month = 1;int _day = 1;// 自定义类型Time _t; }; int main() {Date d;return 0; }运行结果:

-
如果类中没有申请资源时,析构函数可以不写,直接使用编译器生成的默认析构函数,比如
class Date;有资源申请时,一定要写,否则会造成内存泄漏,比如class Stack
3. 拷贝构造函数
3.1 概念
创建对象时用当前已存在的对象初始化新对象称为拷贝。
拷贝构造函数:只有单个形参,**该形参是对本类类型对象的引用(**一般常用const引用),在用已在的类类型对象创建新对象时由编译器自动调用。
c++规定任何自定义类型的拷贝都会调用拷贝构造函数
calss Stack 和 class Date
void fun1(Date d1)
{}
void fun2(Stack st1)
{}
int main()
{Stack st;Date d;fun1(d);//传参时调用Date类型的默认拷贝构造函数fun2(st);//传参时调用Stack类型的默认拷贝构造函数return 0;
}
运行结果:
调用Stack拷贝构造函数时会出现问题,原因我们后面解释。
3.2 特性
-
拷贝构造函数是构造函数的一个重要重载形式
-
拷贝构造函数的参数只有一个且必须是类类型对象的引用,使用传值方式编译器直接报错,因为会引发无穷递归调用。
class Date { public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;}// Date(const Date& d) // 正确写法Date( Date d)//错误写法---拷贝构造函数的参数不能是Date,否则会发生无穷递归{_year = d._year;_month = d._month;_day = d._day;} private:int _year;int _month;int _day; }; int main() {Date d1;Date d2(d1);//传参时将d1拷贝给d:Date d(d1),此时会调用拷贝构造函数,拷贝构造函数右会将d1拷贝给d:Date d(d1)引发无穷递归 }[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-5SrIgELR-1690679807038)(images/image-20230723133609228.png)]
传值拷贝引发的无穷递归:

-
若未显式定义,编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。
class Time { public:Time(){_hour = 1;_minute = 1;_second = 1;}Time(const Time& t){_hour = t._hour;_minute = t._minute;_second = t._second;cout << "Time::Time(const Time&)" << endl;} private:int _hour;int _minute;int _second; }; class Date { private:// 基本类型(内置类型)int _year = 1970;int _month = 1;int _day = 1;// 自定义类型Time _t; }; int main() {Date d1;Date d2(d1);return 0; }运行结果:

-
默认拷贝构造函数的作用
- 对内置类型实现字节序拷贝
- 对自定义类型会调用自定义类型的拷贝构造函数
- 对内置类型实现字节序拷贝
-
c++拷贝自定义对象时为什么要使用拷贝构造函数,和c语言一样全部按字节序拷贝可以吗?
不可以,例如上述
class Stack,若使用默认拷贝构造函数,则对于内置类型就是字节序拷贝,这就会出现内存问题,我们来回顾一下上述代码class Stack { public:Stack(size_t capacity = 3){_array = (DataType*)malloc(sizeof(DataType) * capacity);if (NULL == _array){perror("malloc申请空间失败!!!");return;}_capacity = capacity;_size = 0;}void Push(DataType data){// CheckCapacity();_array[_size] = data;_size++;}~Stack(){if (_array){free(_array);_array = NULL;_capacity = 0;_size = 0;}} private:DataType* _array;int _capacity;int _size; }; void fun1(Date d1) {} void fun2(Stack st1) {} int main() {Stack st;Date d;fun1(d);//传参时调用Date类型的默认拷贝构造函数fun2(st);//传参时调用Stack类型的默认拷贝构造函数return 0; }如果是值拷贝。那么拷贝后st的成员_a和st1的成员_a都指向同一块空间

当st1对象销毁时,会调用析构函数,析构函数会将st1对象_a成员指向的空间释放,此时st对象的_a成员就是野指针了,当st对象销毁时调用析构函数释放野指针指向的空间就会引发内存问题。
因此像
Stack的类我们就需要自己重定义拷贝构造函数,实现深拷贝//自定义拷贝构造函数实现深拷贝Stack(const Stack& st){_array = (DataType*)malloc(sizeof(DataType) * st._capacity);if (nullptr == _array){perror("malloc fail");exit(-1);}memcpy(_array, st._array, sizeof(DataType) * st._size);_capacity = st._capacity;_size = st._size;} int main() {Stack st1;st1.Push(1);st1.Push(2);st1.Push(3);Stack st2(st1);//调用拷贝构造函数完成深拷贝return 0; }运行结果:

-
拷贝构造函数调用场景:
- 使用已存在的对象创建新对象
- 函数参数为类类型对象
- 函数返回值为类类型对象
class Date { public:Date(int year, int minute, 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 temp(d);return temp; } int main() {Date d1(2022, 1, 13);//拷贝构造函数Test(d1);return 0; }

-
-
4. 运算符重载
C++为了增强代码的可读性新增了运算符重载,运算符重载是具有特殊函数名的函数,也具有返回值类型,函数名字以及参数列表,返回值的类型与普通函数相同。
函数名为:operator操作符
函数原型为:返回值类型 operator操作符(参数列表)
注意:
- 不能通过连接其它符号来创建新的操作符:比如
operator@ - 重载操作符必须有一个参数为自定义类型参数
- 用于内置类型的运算符,其含义不能改变,例如:内置类型的+,不能改变其含义
- 用于类成员函数重载时,其形参看起来总是比操作数目少1,因为成员函数的第一个参数为隐藏的this指针
.* :: sizeof ?: .这五个操作符不可以重载
//运算符重载
class Date
{
public:Date(int year, int month, int day){_year = year;_month = month;_day = day;}//运算符重载为成员函数可以访问类的私有成员bool operator==(const Date& d2)//实际上(Date* const this, const Date&d2){return _year == d2._year && _month == d2._month && _day == d2._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;//由于类外部不能直接访问private成员
// //可以通过友元函数解决,这里先将运算符重载作为成员函数.
//}int main()
{Date d1(2023, 7, 23);Date d2(2023, 7, 21);cout << d1.operator==(d2);
运行结果:
这种调用和调用普通成员函数的方法一样看不出可读性,因此调用运算符重载时可以像内置类型一样直接使用运算符。
需要注意的是
d1==d2会被编译器转换为d1.operator(d2)d2==d1会被编译器转换为d2.operator(d1),即操作符的左操作数是调用运算符重载的对象,也是his指针指向的对象
4.1 赋值重载
a.赋值运算符重载格式
- 参数类型:
const T&,引用传递可以提高传参效率 - 返回值类型:
T&,有返回值是为了支持连续赋值,返回引用是为了提高返回的效率。 - 检查是否给自己赋值
- 返回
*this:要符合连续赋值的含义
class Date
{
public:Date(int year = 2023, int month = 7, int day = 28){_year = year;_month = month;_day = day;}Date& operator=(const Date& date){if (this != &date){_year = date._year;_month = date._month;_day = date._day;}return *this;//出了函数后*this还存在,可以返回引用}void Print(){cout << _year << "-" << _month << "-" << _day << endl;}
private:int _year;int _month;int _day;
};
int main()
{Date d1;Date d2(2023, 7, 20);d2 = d1;//调用赋值重载,转化为d2.operator=(d1);d2.Print();return 0;
}
运行结果:
b.编译器会默认生成赋值重载成员函数
如果我们没有显示定义赋值重载,则编译器会默认生成一个复制重载函数,并且该函数完成字节序拷贝,类似于默认生成的拷贝构造函数。对于class Stack这种类型,使用默认的赋值重载函数将会出错,需要使用自定义的赋值重载函数和自定义的拷贝构造函数。
c.赋值运算符只能重载为成员函数,不可以重载为全局函数
上面刚说过,每一个类都会有自己的默认赋值重载函数,如果我们将赋值重载写为全局函数,那么该类就会生成一个默认重载函数,调用时不知道调用类的赋值重载还是调用全局的赋值重载。
d.Date d; Date d2 = d属于拷贝构造函数,不会调用赋值重载
**注意:**如果类中未涉及到资源管理,赋值运算符是否实现都可以;一旦涉及到资源管理则必须要实现。
4.2 自增自减重载
自增自减分为前缀自增、后缀自增、前缀自减、后缀自减。前后缀自增都是单目运算符,那么重载时如何区分重载的对应运算符是前缀还是后缀呢?
C++规定,后缀重载时多增加一个int类型的参数,但调用该函数时不需要显示传递参数,编译器会自动传递
class A
{
public:A(){_a = 1;}A operator++()//重载前缀++{_a++;return *this;}A& operator++(int)//重载后缀++{A tmp(*this);_a++;return tmp;}void Print(){cout << _a << endl;}
private:int _a;
};
int main()
{A a;a++;//编译器转换为a.operator++()a.Print();++a;//编译器转换为a.operator++(0);a.Print();
}
可以看见,对于自定义类型,前置++不需要调用拷贝构造函数,后置++需要调用2次拷贝构造函数。因此对于自定义类型来说前置++的效率更高。
总结:
- 前缀重载运算符效率高
- 定义后缀重载时参数列表给出一个int类型参数作为标记
4.3 取地址操作符重载
取地址及const取地址操作符重载
5. const成员函数
调用成员函数时实际上会传递this指针,this指针指向的是当前对象,我们知道,this指针在函数参数中不可以显示传递接受,那么如果我们要求当前对象的相关信息不可以被更改怎么办呢?我们需要用const修饰this指针,但是这里的const应该放在哪里呢?我们规定,const修饰成员函数时const应该放在函数参数列表最后面。
class Date
{
public:Date(int year = 2023, int month = 7, int day = 28){_year = year;_month = month;_day = day;}Date& operator=(const Date& date)//只能重载为成员函数{if (this != &date){_year = date._year;_month = date._month;_day = date._day;}return *this;//出了函数后*this还存在,可以返回引用}void Print()const//const成员函数表明调用的对象信息不可以更改{cout << _year << "-" << _month << "-" << _day << endl;}
private:int _year;int _month;int _day;
};
int main()
{Date d;d.Print();//权限缩小const Date d1;d1.Print();//权限平移return 0;
}
运行结果:
注意:const成员函数可以和普通成员函数同时存在,调用时优先匹配最合适的
class Date
{
public:Date(int year = 2023, int month = 7, int day = 28){_year = year;_month = month;_day = day;}void Print()const //const成员函数表明调用的对象信息不可以更改--参数为const的成员函数:既可以打印const对象,又可以打印非const对象{cout << _year << "-" << _month << "-" << _day << endl;cout << "void Print()const\n";}//const成员函数重载void Print()//参数为没有被const修饰的成员函数:只能打印非const对象{cout << _year << "-" << _month << "-" << _day << endl;cout << "void Print()\n";}
private:int _year;int _month;int _day;
};
int main()
{Date d1;const Date d2;d1.Print();//void Print()d2.Print();//void Print() constreturn 0;
}
理论上
void Print() const可以打印非const对象,但是这里重载了非const的Print函数,因此d1.Print()时会优先调用最佳匹配的,也就是void Print()
关于const成员函数需要知道的几点
- const对象不可以调用非const成员函数
- 非const对象可以调用const成员函数
- const成员函数内部不可以调用非const成员函数
- 非const成员函数内部可以调用const成员函数
6. 取地址重载
//取地址重载
class Date
{
public:Date(int year = 1, int month = 1, int day = 1){_year = year;_month = month;_day = day;}//普通取地址重载Date* operator&(){return this;}//const取地址重载const Date* operator&()const{return this;}
private:int _year;int _month;int _day;
};
取地址运算符一般不会重载,使用默认生成的即可,除非你不想让别人获取对象的地址
相关文章:
类和对象|六个默认成员函数|const成员函数|运算符重载
文章目录 默认成员构造函数1. 构造函数1.1 概念1.2 特性 2. 析构函数2.1 概念2.2 特性 3. 拷贝构造函数3.1 概念3.2 特性 4. 运算符重载4.1 赋值重载4.2 自增自减重载4.3 取地址操作符重载 5. const成员函数6. 取地址重载 默认成员构造函数 上一节我们说过,空类的大…...
从源码角度去深入分析关于Spring的异常处理ExceptionHandler的实现原理
ExceptionHandler的作用 ExceptionHandler是Spring框架提供的一个注解,用于处理应用程序中的异常。当应用程序中发生异常时,ExceptionHandler将优先地拦截异常并处理它,然后将处理结果返回到前端。该注解可用于类级别和方法级别,…...
04mysql查询语句之查询与分页02
1. 所有有门派的人员信息 ( A、B两表共有) INSERT INTO t_dept(deptName,address) VALUES(华山,华山); INSERT INTO t_dept(deptName,address) VALUES(丐帮,洛阳); INSERT INTO t_dept(deptName,address) VALUES(峨眉,峨眉山); INSERT INTO t_dept(deptN…...
原型模式——对象的克隆
1、简介 1.1、概述 可以通过一个原型对象克隆出多个一模一样的对象,该模式被称为原型模式。 在使用原型模式时,需要首先创建一个原型对象,再通过复制这个原型对象来创建更多同类型的对象。 1.2、定义 原型模式(Prototype Patt…...
[SQL挖掘机] - 多表连接
介绍: 在 SQL 中,多表连接是指将多个表根据某些条件进行联接,以获取相关联的数据。这允许我们跨多个表进行查询,并且根据表之间的关系获取所需的结果。 作用: 当在多个表中存储相关数据时,使用多表连接可以将这些表组合起来以获…...
Day 14 C++ 对象的初始化和清理
目录 为什么要进行对象的初始化和清理 构造函数和析构函数 构造函数(Constructor) 构造函数语法 调用时机 构造函数的调用方式 括号法 显式法 隐式转换法 构造函数分类 分类方式 按参数分为有参构造和无参构造 按类型分为普通构造和拷贝构造…...
Delphi7最佳登录窗体设计
Delphi7我们这里用登录窗体来做演示。输入正确用户名和密码后,登录窗体释放,显示主窗体。 方法/步骤 1.打开Delphi7集成开发环境,在默认工程的Form1窗体放置一个Label1控件,拖动控件边界调整大小,并将Object Inspect…...
动脑学院Jetpack Compose学习笔记
最近b站学习了一下Compose相关内容,整理了相关笔记,仅供大家参考。 资源链接如下,象征性收取1个积分 https://download.csdn.net/download/juliantem/88125198...
Qt中线程的使用
Qt中线程的使用 在qt中线程的使用有两种方式,第一种就是创建一个类继承QObject类,之后使用moveToThread函数将线程添加到类中。另一种就是创建一个类继承QThread类,在类中实现run函数。 第一种方式: 1、首先创建一个自定义的类…...
基于YOLOv8开发构建蝴蝶目标检测识别系统
在前面的一篇博文中已经很详细地描述了如何基于YOLOv8开发构建自己的个性化目标检测模型,感兴趣的话可以看下: 《基于YOLOv8开发构建目标检测模型超详细教程【以焊缝质量检测数据场景为例】》 本文的主要目的就是基于YOLOv8来开发构建细粒度的蝴蝶目标…...
【已解决】电脑连上网线但无法上网
文章目录 案例情况解决方案必要的解决方法简要概括详细步骤1、打开控制面板2、打开更改适配器设置3、 找Internet协议版本44、修改配置 可能有用的解决方法 问题解决原理Internet 协议版本 4(TCP/IPv4)确保IP地址和DNS服务器设置为自动获取 案例情况 网…...
Linux 学习记录57(ARM篇)
Linux 学习记录57(ARM篇) 本文目录 Linux 学习记录57(ARM篇)一、外部中断1. 概念2. 流程图框 二、相关寄存器1. GIC CPU Interface (GICC)2. GIC distributor (GICD)3. EXTI registers 三、EXTI 寄存器1. 概述2. 内部框图3. 寄存器功能描述4. EXTI选择框图5. EXTI_EXTICR1 &…...
Doris注意事项,Doris部署在阿里云,写不进去数据
1.Doris官网 Doris官网https://doris.apache.org/ 2.根本原因 本地idea访问FE,FE会返回BE的地址,但是在服务器上通过ip addr查看,发现只有局域网IP,所以FE返回了局域网的IP,导致idea连接不上BE 3.解决办法 重写Ba…...
502 Bad GateWay报错的解决方法
什么是502 bad gateway 报错 简单来说 502 是报错类型代码 bad gateway 错误的网关。是Web服务器作为网关或代理服务器时收到无效的响应。 用我们的口语说就是运行网站的服务器暂时挂了(不响应)。 产生错误的原因 1.连接超时 我们向服务器发送请求 由于服务器当前链接太多&am…...
openpnp - ReferenceStripFeeder 改版零件
文章目录 openpnp - ReferenceStripFeeder 改版零件概述笔记整体效果散料飞达主体磁铁仓盖板飞达编带中间压条飞达编带两边压条装配体用的8mm编带模型END openpnp - ReferenceStripFeeder 改版零件 概述 官方推荐了ReferenceStripFeeder的模型smd_strip_feeders_mod_tray.zip…...
VoxPoser:使用大语言模型(GPT-4)来对机器人操作的可组合三维值图【论文解读】
这是最近斯坦福的李飞飞团队的一篇论文:VoxPoser: Composable 3D Value Maps for Robotic Manipulation with Language Models 主要是通过大语言模型LLM和视觉语言模型VLM结合,来对机器人做各种日常操作,我们可以先来看下实际效果:大语言模型…...
RISC-V公测平台发布 · 第一个WEB Server “Hello RISC-V world!”
RISC-V公测平台Web Server地址:http://175.8.161.253:8081 一、前言 Web Server是互联网应用的基础设施,无论是用户访问网站,还是后端服务提供商和开发者构建各种应用程序,Web Server都在其中扮演着至关重要的角色。 显而易见…...
Linux 发行版 CentOS 于 Ubuntu 软件的安装、卸载、查找
CentOS于Ubuntu 内核都是Linux,是一样的。 CentOS 软件格式 .rpm sudo yum [-y] [ install | remove | search ] 软件名称 install 安装 remove 移除 search 搜索 Ubuntu 软件格式 .deb sudo apt [-y] [ install | remove | search ] 软件名称 install 安装 remove…...
cmd相关操作命令
1.根据端口号查询对应进程的PID netstat -ano | findstr 端口号 例如:netstat -ano | findstr 9080;该端口所属进程的PID为6684 2.根据PID查询对应进程 tasklist | findstr PID 例如:tasklist | findstr 6684;该PID所属进程名为…...
使用EM算法完成聚类任务
EM算法(Expectation-Maximization Algorithm)是一种基于迭代优化的聚类算法,用于在无监督的情况下将数据集分成几个不同的组或簇。EM算法是一种迭代算法,包含两个主要步骤:期望步骤(E-step)和最…...
基于ASP.NET+ SQL Server实现(Web)医院信息管理系统
医院信息管理系统 1. 课程设计内容 在 visual studio 2017 平台上,开发一个“医院信息管理系统”Web 程序。 2. 课程设计目的 综合运用 c#.net 知识,在 vs 2017 平台上,进行 ASP.NET 应用程序和简易网站的开发;初步熟悉开发一…...
连锁超市冷库节能解决方案:如何实现超市降本增效
在连锁超市冷库运营中,高能耗、设备损耗快、人工管理低效等问题长期困扰企业。御控冷库节能解决方案通过智能控制化霜、按需化霜、实时监控、故障诊断、自动预警、远程控制开关六大核心技术,实现年省电费15%-60%,且不改动原有装备、安装快捷、…...
postgresql|数据库|只读用户的创建和删除(备忘)
CREATE USER read_only WITH PASSWORD 密码 -- 连接到xxx数据库 \c xxx -- 授予对xxx数据库的只读权限 GRANT CONNECT ON DATABASE xxx TO read_only; GRANT USAGE ON SCHEMA public TO read_only; GRANT SELECT ON ALL TABLES IN SCHEMA public TO read_only; GRANT EXECUTE O…...
【论文笔记】若干矿井粉尘检测算法概述
总的来说,传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度,通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...
新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...
浪潮交换机配置track检测实现高速公路收费网络主备切换NQA
浪潮交换机track配置 项目背景高速网络拓扑网络情况分析通信线路收费网络路由 收费汇聚交换机相应配置收费汇聚track配置 项目背景 在实施省内一条高速公路时遇到的需求,本次涉及的主要是收费汇聚交换机的配置,浪潮网络设备在高速项目很少,通…...
LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
GitFlow 工作模式(详解)
今天再学项目的过程中遇到使用gitflow模式管理代码,因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存,无论是github还是gittee,都是一种基于git去保存代码的形式,这样保存代码…...
MacOS下Homebrew国内镜像加速指南(2025最新国内镜像加速)
macos brew国内镜像加速方法 brew install 加速formula.jws.json下载慢加速 🍺 最新版brew安装慢到怀疑人生?别怕,教你轻松起飞! 最近Homebrew更新至最新版,每次执行 brew 命令时都会自动从官方地址 https://formulae.…...









