C++类和对象万字详解(典藏版)

在这里插入图片描述

文章目录

  • 前言
  • 认识类和对象
    • 使用 struct 定义类
    • class 定义类
    • 类的声明和定义分离
    • 类大小的计算
    • this指针
      • this指针的常见的面试题
  • 构造函数与构析函数
    • 构造函数
      • 初始化列表
    • 构析函数
    • 默认生成的构造函数和构析函数
  • 拷贝构造函数
    • 默认类型转化与 explicit 关键字
  • static 成员变量
  • 运算符重载
  • 友元
    • 友元函数
    • 友元类
  • 内部类
  • 匿名对象

大家好,我是纪宁。
类和对象是C++编程中非常重要的概念,在生活中我们要经常使用类和对象来解决问题,掌握类和对象的使用方法对于编写高质量、高效率的C++代码至关重要。这篇文章将讲解类和对象相关的内容。

前言

首先C++是兼容C的,所以 C 的语法在 C++中 99%都可以使用,但根据一些C++大佬的说法是:“学了C++之后就不想再使用C了”,到底是怎么回事呢?

在C中,如果我们要定义一个可以描述事物的集合是,通常会定义一个结构体的复杂类型,里面可以存放多种描述这个事物特征的成员变量。但是,如果我们想表示这个事物可以具体进行那些操作的时候,还要另外设置函数,并将这个结构体类型作为参数传递进去,对这个函数进行封装,形成一个个‘方法’(成员函数)。在需要使用这个事物的某些操作的时候,只需要调用这些方法即可。
但是!众所周知,C++是对C的改进和提升,C++中定义了一种新的编程方式:面向对象编程的,在一个类中,可以将数据与操作数据的方法封装在一起,描述一类对象的属性和行为,形成一个或多个对象,从而实现程序的可重用性、可扩展性。

认识类和对象

使用 struct 定义类

在C中,struct 用来定义结构体,而在C++中,struct 也可以用来定义类

定义一个汽车类 Car

struct Car
{double price;int year;
};

这个类中包含了一辆汽车的基本信息,现在可以尝试通过这个汽车类定义一个对象 car,并打印它的基本信息。

int main()
{Car car;car.year = 1997;car.price = 134567.896;cout << car.year << endl;cout << car.price << endl;return 0;
}

但是,一个汽车肯定不只有属性,还有各种功能,如果我们想调用这些功能应该如何做呢?答案是向类中添加成员函数,这种函数被称为类的成员函数或者类的方法。我们可以尝试在汽车这个类添加一些汽车的方法或功能并调用这些方法。

添加汽车启动、行驶、熄火

struct Car
{double price;int year;void Startup(){cout << "汽车,启动!!!" << endl;}void Drive(){cout << "汽车行走了50km,用了半小时" << endl;}void Brake(){cout << "汽车在你一直踩刹车中停止!" << endl;}};int main()
{Car car;car.Startup();car.Drive();car.Brake();return 0;
}

运行结果:
在这里插入图片描述
现在,我们可以继续在Car这个类中添加其他的方法,但在此之前,要先补充一下基础知识。

class 定义类

要说到再C++中使用类,大家应该再熟悉不过的就是 class 了,它在定义类的基础语法上和 struct 是相同的。

class Car
{double price;int year;void Startup(){cout << "汽车,启动!!!" << endl;}void Drive(){cout << "汽车行走了50km,用了半小时" << endl;}void Brake(){cout << "汽车在你一直踩刹车中停止!" << endl;}
};

但是在调用的时候,编译器却报错了。
在这里插入图片描述
原因是在 class 定义的类中,里面的成员默认是私有的,只有在类内部才可以使用;而struct 定义的类里面的成员默认是公开的,在类内外都可以使用。所以在 class 定义的类中要加入访问限定符

  • public 公有
  • protected 保护
  • private 私有

那么,经过访问限定符修饰后的类就变成了:

class Car
{public:void Startup(){cout << "汽车,启动!!!" << endl;}void Drive(){cout << "汽车行走了50km,用了半小时" << endl;}void Brake(){cout << "汽车在你一直踩刹车中停止!" << endl;}private:double price;int year;
};

一般会将事物的基本属性放在私有里面,然后将事物的一些方法和功能函数放在公有里面。

类的声明和定义分离

如果要将类的声明放在.h文件中,可以使用如下的方法

class Car
{
public:void Startup();void Drive();void Brake();bool Promote(){return 0;}
private:double price;int year;
};

较长的函数,可以将它的声明放在.h文件中,较短的函数直接将函数定义放在类里。
声明后的.cpp文件中只需要写类的成员函数的定义部分就可以了。但是要在函数名前加 类名::,如下

void Car::Startup()
{cout << "汽车,启动!!!" << endl;
}
void Car::Drive()
{cout << "汽车行走了50km,用了半小时" << endl;
}
void Car::Brake()
{cout << "汽车在你一直踩刹车中停止!" << endl;
}

在这里插入图片描述这样,就可以在 .cpp文件中正常调用类的成员函数了。

类大小的计算

关于类的大小,计算规则有点类似于结构体的内存对齐,这里需要注意的一点是:类大小只计算成员变量大小(需要考虑内存对齐),而成员函数其实是储存在公共代码区的。

变量的声明和定义的区别:是否开了空间

一个类中,如果没有成员变量,它定义的对象大小并不是0而是1。这种类在定义对象的时候会开一个字节的空间,但这个字节不存储有效数据,作用是 标识定义的对象存在过。

this指针

如图,当d1调用成员函数 Print 的时候,该函数是如何知道应该设置d1对象,而不是设置d2对象呢?
在这里插入图片描述
其实,C++编译器在每个成员函数里定义了一个指针 this 作为成员函数的第一个形参,同时将调用此函数的对象地址作为参数传过去,默认在成员函数中访问成员变量就是对这个 this 指针指向对象里的成员变量进行访问。

this指针不能显式的写出this 相关的实参和形参,但在类中可以显式的使用 this 指针。如图:
在这里插入图片描述

this指针的常见的面试题

this 指针存在哪里?

前面已经学习过类的大小是由类中成员变量决定的,所以this指针肯定不是存储在类中。this指针是成员函数中定义的形参,与局部变量一样,一般存在函数栈帧上。但不同的编译器会对存储位置稍有优化,因为this指针会经常使用到,所以vs将this指针存储在 eax 这个寄存器中方便快速调用。

构造函数与构析函数

曾经,我们在定义栈,列表等这种复杂结构的时候,每次定义对应变量或对象后都要及时进行初始化,在即将要出作用域的时候要进行销毁。但粗心的我们经常会忘记调用初始化函数和销毁函数,但是有了C++后就可以利用构造函数和析构函数解决这一问题了。

构造函数

构造函数的定义写在类里面,用于初始化这个类创建的对象,构造函数有如下特征:

  • 函数名与类名称相同
  • 无返回值(void 都不用写)
  • 对象实例化时编译器自动调用对应的构造函数
  • 支持重载

如图,对日期类定义构造函数(全缺省非常合适)
声明
在这里插入图片描述
定义
在这里插入图片描述

那么,定义日期类的实例化对象的时候既可以使用如下方法:

Date d1;
Date d2(2023, 10, 24);
Date d3(2023);

当不传递参数的时候(也不需要带括号),默认实例化对象成员变量全部初始化为1;当正常传参的时候,就将实例化对象初始化为需要的值;当参数‘不足’时,就利用函数缺省的规则,优先对前面的形参进行传值。

初始化列表

初始化列表格式:以一个冒号开始,接着是一个以逗号分隔的数据成员列表,每个"成员变量"后面跟一个放在括号中的初始值或表达式。
在这里插入图片描述
相当于如下正常的构造函数
在这里插入图片描述
那为什么要使用初始化列表呢?

有的成员变量只能初始化一次,如const 限制的变量引用定义的成员变量无默认构造函数的自定义类型成员等,所以只能使用初始化列表来初始化。
在这里插入图片描述
但需要注意一点:引用定义的成员变量在使用初始化列表进行初始化的时候,不能使用形参来给引用赋值,否则在构造函数结束后,引用的成员变量就会变为随机值。
初始化列表的顺序
成员变量在类中声明次序就是其在初始化列表中的初始化顺序,与其在初始化列表中的先后次序无关。所以为了避免出现歧义,建议声明顺序和初始化列表顺序保持一致。

初始化列表和函数体内初始化可以配合使用

如下面的例子:
在这里插入图片描述
在这里插入图片描述
初始化列表的时候会将所有成员全部定义,如果在初始化列表的时候没有显示写某些成员,编译器也会定义,只不过内置类型会被初始化为随机值,而自定义类型则会去调用它自己的默认构造函数。定义时就要初始化的变量必须显示写出来。

构析函数

定义方法:在类名前面加~,无参,无返回值。写在类中,在对象生命周期结束时自动调用,用来释放动态内存申请的资源。
如栈的构析函数:

~Stack()
{if (_array){free(_array);_array = NULL;_capacity = 0;_size = 0;}
}

默认生成的构造函数和构析函数

不写构造函数和构析函数的情况下,编译器会生成默认的构造函数和析构函数。系统默认生成的,对此对象内置类型的成员变量不做处理,自定义类型的成员变量自动调用它的构造函数和析构函数(其实就是一种辅助,将写好的,能用的调用过来)。如果写了对应的构造函数和析构函数,编译器会优先调用。
对于内置类型不自动初始化的漏洞,C++11在原有基础上打了一个补丁,即:允许在声明成员变量的时候给初始值。
在这里插入图片描述
这样,即使内置类型没有在构造函数里自动初始化,也不影响它有初始值。

拷贝构造函数

在C语言中,有时会使用浅拷贝,如在结构体传参的时候不传指针,直接将结构体传过去,这种直接传值,形参进行拷贝的情况叫浅拷贝(也叫值拷贝),即将变量的值原封不动的复制一份。

但是,这种浅拷贝在C++中是有风险的,当在C++中拷贝对象的时候,如果实例化对象中申请了动态的空间,按值拷贝的话会导致指针指向同一块空间,而C++中有析构函数,在对象声生命周期结束时会自动调用,则这块空间会被释放两次,第二次释放的时候就产生的野指针和越界访问的问题。

编译器自己其实也生成了默认的拷贝构造函数,这个默认生成的拷贝构造函数是按值拷贝的,如果未涉及到内存申请,那么这样的值拷贝是可行的,但如果涉及到了内存申请,那么值拷贝就对导致同一块空间被释放两次,最终导致程序崩溃。

拷贝构造是函数构造的一种重载,那么它的形式和函数构造的差不多的,唯一需要注意的是,形参必须用引用来定义。如果不传引用,自定义类型传参的时候就会引发无穷递归:拷贝的时候要调用拷贝构造函数,拷贝构造函数传参的时候又要进行拷贝…无穷尽了。

拷贝构造函数通常为了规避写错,会在形参定义前加 const

如下面的代码:

Date::Date(const Date& dd)
{_year = dd._year;_month = dd._month;_day = dd._day;
}
Stack(Stack&st)
{_a = (int*)malloc(sizeof(int) * st.capacity);if (_a == nullptr){perror("malloc fail");exit(-1);}memcpy(_a, st._a, sizeof(int) * st._top);_top = st._top;_capacity = st._capacity;
}

就用上面的日期类来举例子看拷贝构造的内部原理:
在这里插入图片描述
在这里插入图片描述

将d2拷贝给d3,调用拷贝构造函数,如上图,dd是d2的别名,而拷贝构造函数内部的this指针是指向d3的,即将对象d2成员变量的值依次赋值给d3。

默认类型转化与 explicit 关键字

构造函数不仅可以构造与初始化对象,对于单个参数或者除第一个参数无默认值其余均有默认值的构造函数,还具有类型转换的作用。
先解释一个点:默认不同类型再进行赋值的时候,都要进行隐式类型转化(前提是能转化),转化的过程是先创建一个临时变量来存储转化后的,然后再进行同类型变量之间的赋值。
内置类型对象也可以转化为自定义类型的对象,能支持这个转换,是有自定义对象有带缺省值的构造函数(自己定义的构造函数)。
用内置类型直接给对象赋值/初始化的时候,实际编译器背后会用这个内置类型通过带缺省值默认构造函数构造一个无名对象,最后用无名对象给d1对象进行赋值。
在这里插入图片描述
但是说实话这种代码的可读性不是非常好,为了防止这种情况的出现,我们可以使用explicit关键字来对构造函数进行修饰,explicit修饰过的构造函数,禁止类型转换
在这里插入图片描述
再次进行上面情况的赋值时,编译器就会报错:
在这里插入图片描述

static 成员变量

声明为static的类成员称为类的静态成员,用static修饰的成员变量,称之为静态成员变量;用 static 修饰的成员函数,称之为静态成员函数。静态成员变量一定要在类外进行初始化。

静态成员变量
在这里插入图片描述

静态成员函数
在这里插入图片描述
使用样例
在这里插入图片描述

类的静态成员的特性

  1. 静态成员为所有类对象所共享,不属于某个具体的对象,存放在静态区
  2. 静态成员变量必须在类外定义,定义时不添加static关键字,类中只是声明
  3. 类静态成员即可用 类名::静态成员 或者 对象.静态成员 来访问
  4. 静态成员函数没有隐藏的this指针,不能访问任何非静态成员
  5. 静态成员也是类的成员,受public、protected、private 访问限定符的限制

面试题目 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;void TestA()
{cout << A::GetACount() << endl;A a1, a2;A a3(a1);cout << A::GetACount() << endl;
}int main()
{TestA();
}

程序解释:在类的私有部分定义一个静态成员变量,每个类都共享这个成员变量。在类外对静态成员变量定义并初始化为0,每调用一次构造函数和构造拷贝函数说明就多创建了一个对象,就对静态成员变量的值加1,等到最后程序即将结束的时候再利用 类:: 成员 来访问成员函数得到它的成员变量的值。这个成员变量的值就是程序中创建对象的个数。

运算符重载

内置类型使用运算符的时候,编译器会将它转化为指令,自定义类型却不可以直接使用运算符。C++中的运算符重载可以让自定义类型可以直接使用运算符。
使用方法:在使用的时候还是正常使用运算符,但需要在类中使用 operator关键字提前定义好对应的运算符重载函数。
如下面的日期类的+=运算符重载(定义与声明分离)

int Date::GetMonth(int year,int month)
{int Month[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 Month[month];}
}
Date& Date::operator+=(int x)
{_day+= x;while (_day > GetMonth(_year, _month)){_day -= GetMonth(_year, _month);_month++;if (_month == 13){_year++;_month = 1;}}return *this;
}

日期类的 >运算符重载代码(<直接对这个进行逻辑取反)

bool Date::operator>(const Date&d)
{if (_year > d._year){return true;}if (_year == d._year && _month > d._month){return true;}if (_year == d._year && _month > d._month && _day > d._day){return true;}return false;
}

日期类的==运算符重载代码

bool Date::operator==(const Date& d)
{return _year == d._year&& _month == d._month&& _day == d._day;
}

日期类-=运算符重载

Date& Date::operator-= (int x)
{if (x < 0){*this += -x;}else{_day -= x;while (_day <= 0){_month--;if (_month == 0){_year--;_month = 12;}_day += GetMonth(_year, _month);}}return *this;
}

日期类-运算符重载(两个日期相减)


int Date::operator-(const Date& d)
{int flag = 1;Date max = *this;Date min = d;int count = 0;if (max < min){max = d;min = *this;flag = -1;}while (min != max){count++;min++;}return count * flag;
}

通俗的来讲,就是对 this 指针指向的对象的成员进行操作,使其在某种意义上根据使用者的意愿达到使用运算符进行计算的程度。
需要注意的点:运算符需要什么样的返回类型,运算符重载时就要使用什么样的返回值;比较函数需要放在类里。
是否使用引用返回?
出了作用域还未销毁的,就可以使用引用返回,如this指针(在+=,-=等的重载直接对this指针操作时可以使用引用返回);当在+、- 等需要先拷贝this指针内容的情况下,不能用引用返回,因为这些拷贝的对象出作用域后会被销毁。

友元

友元提供了一种突破封装的方式,有时提供了便利。但是友元会增加耦合度,破坏了封装,所以友元不宜多用。

代码耦合度
代码耦合度是指代码中的模块与模块之间的相互依赖程度。当模块之间相互依赖度高时,就会导致代码的耦合度高,这会增加代码的复杂度,阻碍代码的维护和扩展。

友元分为:友元函数和友元类

友元函数

友元函数可以直接访问类的私有成员,它是定义在类外部的普通函数,不属于任何类,但需要在类的内部声明,声明时需要加friend关键字。

如要对 << 和 >> 进行运算符重载

在类里进行友元声明
在这里插入图片描述
此函数在类外也可访问这个类的私有
在这里插入图片描述
代码详解

class Date
{friend ostream& operator<<(ostream& _cout, const Date& d);friend istream& operator>>(istream& _cin, Date& d);
public:Date(int year = 1, int month = 1, int day = 1)//构造函数:_year(year), _month(month), _day(day), def(_year), zop(month){}~Date(){_year = _month = _day = 1;}Date(const Date& d):zop(d.zop), def(d.def){cout << d.def << "d2.def" << endl;_year = d._year;_month = d._month;_day = d._day;}void Print(){cout << _year << '/' << _month << '/' << _day << endl;cout << _year << '/' << _month << '/' << _day << endl;cout << def << '/' << zop << endl;}
private:int _year;int _month;int _day;int& def;const int zop;
};ostream& operator<<(ostream& _cout,const Date&d){cout << d._year << "/" << d._month << "/" << d._day << endl;return _cout;
}
istream& operator>>(istream& _cin, Date& d){cin >> d._year;cin >> d._month;cin >> d._day;return _cin;
}
int main()
{Date d1;cout << d1;Date d2(2023, 11, 1);cout << d2;Date d3;cin >> d3;cout << d3;return 0;
}

友元类

友元类的所有成员函数都可以是另一个类的友元函数,都可以访问另一个类中的非公有成员。

友元类有以下特性:

  • 友元关系是单向的,不具有交换性。

比如在Time类中声明Date类为其友元类,那么可以在Date类中直接访问Time类的私有成员变量,但想在Time类中访问Date类中私有的成员变量则不行。

  • 友元关系不能传递
    如果C是B的友元, B是A的友元,则不能说明C时A的友元。
  • 友元关系不能继承

内部类

内部类是指在类内定义的类,也被称为嵌套类。内部类可以访问外部类的所有成员,包括私有成员。内部类是一个独立的类,它不属于外部类,更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任何优越的访问权限。

注意:内部类就是外部类的友元类,参见友元类的定义,内部类可以通过外部类的对象参数来访问外部类中的所有成员。但是外部类不是内部类的友元。

内部类可以帮助我们更好的封装类的实现细节,同时也可以在外部类的成员函数中方便地使用内部类,从而减少代码的复杂度。

注意点

  1. 内部类可以定义在外部类的public、protected、private都是可以的。
  2. 注意内部类可以直接访问外部类中的static成员,不需要外部类的对象/类名。
  3. sizeof(外部类)=外部类,和内部类没有任何关系。

内部类举例

class Dog
{
private:static int k;int h;
public://定义Goddess类,是Dog的内部类class Goddess // Goddess天生就是Dog的友元{public:void foo(const Dog& a){cout << k << endl;//OKcout << a.h << endl;//OK}};
};
int Dog::k = 1;
int main()
{Dog::Goddess b;b.foo(Dog());return 0;
}

代码解读:Goddess就是一个普通类,只是受Dog的类域和访问限定符的限制。Goddess天生是Dog的友元类,可以访问Dog的私有;但Gog却不是Goddess的友元类,Dog不能访问Goddess的任何私有!

匿名对象

在C++中,我们可以创建匿名对象。所谓匿名对象是指创建一个没有名字的临时对象。这种对象可以直接在函数调用或表达式中使用,而不需要定义变量名。

语法:类名()
如图,Date 是一个类
在这里插入图片描述
它的声明周期只有这一行,有时候需要对象来访问成员的时候用一个匿名对象就很好用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/129001.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【云原生基础】了解云原生,什么是云原生?

&#x1f4d1;前言 本文主要讲了云原生的基本概念和原则的文章&#xff0c;如果有什么需要改进的地方还请大佬指出⛺️ &#x1f3ac;作者简介&#xff1a;大家好&#xff0c;我是青衿&#x1f947; ☁️博客首页&#xff1a;CSDN主页放风讲故事 &#x1f304;每日一句&#x…

分享一个抖音视频解析神器~

怎么样下载抖音视频&#xff1f;相信很多人都有过这样的困惑。作为一个资深短视频剪辑工作者&#xff0c;常常需要用到各种视频素材&#xff0c;其中不乏需要从抖音上下载的&#xff0c;因此我也尝试过许多下载工具&#xff0c;但是效果都不大满意&#xff0c;直到有一次朋友给…

SpringBoot可以同时处理多少请求?

前言 前两天面试的时候&#xff0c;面试官问我&#xff1a;一个ip发请求过来&#xff0c;是一个ip对应一个线程吗&#xff1f;我突然愣住了&#xff0c;对于SpringBoot如何处理请求好像从来没仔细思考过&#xff0c;所以面试结束后就仔细研究了一番&#xff0c;现在就来探讨一…

C++——list

目录 list介绍 list的函数接口 构造函数 push_front和pop_front push_back和pop_back insert erase 迭代器 front和back size resize empty clear list::sort unique reverse 迭代器的实现 list介绍 list是一种可以在常数范围内在任意位置进行插入和删除的序列…

“AI换脸诈骗”来势汹汹,三个层面科学应对……

当前&#xff0c;AI技术的广泛应用为社会公众提供了个性化智能化的信息服务&#xff0c;也给网络诈骗带来可乘之机&#xff0c;如不法分子通过面部替换语音合成等方式制作虚假图像、音频、视频仿冒他人身份实施诈骗、侵害消费者合法权益。你认为AI诈骗到底应该如何防范&#xf…

Selenium3-获取元素的css属性

来个元素CSS值 代码1: 通过javaScript执行脚本获取css值 String jsStr "return document.getElementById(\"buyers\").style.getPropertyValue(width)"; Object o ((JavascriptExecutor) driver).executeScript(jsStr); System.out.println(o.toString(…

短视频平台Roposo入驻印尼,会成为下一个Tiktok吗

Roposo是一个印度本土的短视频平台&#xff0c;功能和风格都和Tiktok很相似。 早在2020年7月&#xff0c;印度下令封禁了多个app&#xff0c;其中就包括了TikTok。在那之前&#xff0c;TikTok已经在印度累计了约2亿的用户&#xff0c;基数已经非常的大&#xff0c;那么被封禁之…

北京君正X2600处理器亮相ELEXCON 2023,打造多核异构跨界新价值

伴随下游应用持续丰富&#xff0c;细节需求不断增多&#xff0c;标准化产品已越来越难以满足市场需求&#xff0c;芯片方案提供商需要不断深入行业&#xff0c;根据市场需求推出适配的产品。在这样的背景下&#xff0c;北京君正迅速推出X2600系列多核异构跨界处理器&#xff0c…

ONNX的结构与转换

ONNX的结构与转换 1. 背景2. ONNX结构分析与修改工具2.1. ONNX结构分析2.2. ONNX的兼容性问题2.3. 修改ONNX模型 3. 各大深度学习框架如何转换到ONNX&#xff1f;3.1. MXNet转换ONNX3.2. TensorFlow模型转ONNX3.3. PyTorch模型转ONNX3.4. PaddlePaddle模型转ONNX3.4.1. 简介3.4…

高阶数据结构学习——LRU Cache

文章目录 1、了解LRU Cache&#xff08;Least Recently Used缩写&#xff09;2、代码实现 1、了解LRU Cache&#xff08;Least Recently Used缩写&#xff09; Cache是缓存&#xff0c;在磁盘和内存之间&#xff0c;内存和寄存器之间都存在&#xff0c;CPU和内存之间存在三级缓…

基于PyTorch的中文情绪分析器设计与开发

收藏和点赞&#xff0c;您的关注是我创作的动力 文章目录 概要 一、相关基础理论2.1 主流深度学习框架2.2 神经网络2.2.1 神经网络基础 二、中文情感分类模型构建3.1 开发环境3.2 数据部分3.3 文本特征提取3.3.1、过滤标点符号3.3.2 中文分词、单词过滤 三 运行结果与分析五 结…

快速批量重命名:高效修改文件名并转换为大写扩展名

在文件管理中&#xff0c;批量重命名文件是一个常见的需求。通过快速批量重命名&#xff0c;我们可以高效地修改文件名并将扩展字母转换为大写形式。这样做不仅可以提高文件的可读性&#xff0c;还可以更好地组织和管理文件。用云炫文件管理器可以快速批量重命名&#xff0c;能…

k8s之pod进阶---资源限制与探针

目录 一、资源限制 二、探针&#xff08;健康检查&#xff09; 2.1 含义 2.2 探针的三种规则 2.3 probe支持三种检查方法 2.4 探针的示例 1、存活探针&#xff1a;livenessProbe &#xff08;1&#xff09;exec方式 &#xff08;2&#xff09;httpGet方式 &#xff08;…

如何使用ps制作ico图标文件

如何使用ps制作ico图标文件 Chapter1 如何使用ps制作ico图标文件Chapter2 ICOFormat.8bi&#xff08;Photoshop Ico、Cur插件&#xff09;的下载使用1. ICOFormat.8bi的作用2. ICOFormat.8bi使用 Chapter3 ps手机计算机图标教程,手绘设计精美手机APP软件图标的PS教程步骤 01 制…

目标检测中常见指标 - mAP

文章目录 1. 评价指标2. 计算示例3. COCO评价指标 1. 评价指标 在目标检测领域&#xff0c;比较常用的两个公开数据集&#xff1a;pascal voc和coco。 目标检测与图像分类明显差距是很大的&#xff0c;在图像分类中&#xff0c;我们通常是统计在验证集当中&#xff0c;分类正…

佳易王定制开发流水线商品标签自动打印软件,打印格式可定制

佳易王定制开发流水线商品标签自动打印软件&#xff0c;打印格式可以定制 软件特色&#xff1a; 定制试用商品标签打印管理V16.0&#xff0c;打印标签可以自动计算到期日期和品控日期&#xff0c;并打印品名、包装规格、生产日期、到期日期、储存条件、生产包装、品控日期等信…

阿里测试8年,肝到P8只剩他了····

在阿里工作了8年&#xff0c;工作压力大&#xff0c;节奏快&#xff0c;但是从技术上确实得到了成长&#xff0c;尤其是当你维护与大促相关的系统的时候&#xff0c;熬到P7也费了不少心思&#xff0c;小编也是个爱学习的人&#xff0c;把这几年的工作经验整理成了一份完整的笔记…

Spring Cloud智慧工地源码,利用计算机技术、互联网、物联网、云计算、大数据等新一代信息技术开发,微服务架构

智慧工地系统充分利用计算机技术、互联网、物联网、云计算、大数据等新一代信息技术&#xff0c;以PC端&#xff0c;移动端&#xff0c;设备端三位一体的管控方式为企业现场工程管理提供了先进的技术手段。让劳务、设备、物料、安全、环境、能源、资料、计划、质量、视频监控等…

Python自动化运维监控——批量监听页面发邮件(自由配置ini文件+smtplib)

一、程序样式 1.listen.ini配置文件 2.监控页面 3.日志 二、核心点 smtplib库&#xff1a;这里使用了smtp.qq.com与smtp.163.com两个发送邮件的地址&#xff0c;使用邮箱用户名与授权码来实现登录&#xff0c;端口都使用465&#xff0c;最后抛出异常&#xff0c;finally里…

springboot的请求与响应

一&#xff0c;简单参数 Get请求&#xff1a;只需要在postman中的Params参数与方法中的形参一致就可以Post请求与Get方法一致只需要在 如果参数名不一致--通过RequestParam中的value属性执行请求参数名 RequestParam(name "name",required false) //表示name参数不是…