[C++入门系列]——类和对象下篇

27914845d1294061a2016053f3096778.gif

作者主页

📚lovewold少个r博客主页

   ⚠️本文重点:C++类和对象下篇知识点讲解

👉【C-C++入门系列专栏】:博客文章专栏传送门

😄每日一言:宁静是一片强大而治愈的神奇海洋!

09dedf485a18435d83b9758fc0bdbeec.gif

 

目录

前言

再谈构造函数

初始化列表 

explicit关键字

static成员

静态成员函数

静态成员特性总结

友元

友元函数

友元类

内部类

再度理解类和对象

总结


前言

        前段时间主要在博客中讲述了C++类和对象中篇的一些知识点,我们发现C++类特性功能有多强大,同时也相应很复杂。在前面的文章中主要涉及到C++默认的成员函数,包括不限于构造函数,析构函数,拷贝构造函数,赋值运算符重载以及const成员函数等内容,踏上了类和对象的编程之旅。详细请看类和对象中篇文章。

        本章会主要从类和对象的更多特性入手,再次剖析构造函数,通过这篇文章的知识点和前面形成连贯理解,对类和对象有更多的理解。同时,本篇文章还会谈及Static成员,友元,内部类,等关键知识点点讲解,深刻理解C++类和对象中的封装意义。学习C++的过程中,难点一是概念情况较为复杂,需要结合代码去深入理解,同时有很多知识点需要去记忆。C++特性的数量之多就意味着很难去全部使用,大多数人需要掌握的是常用特性,同时对与很多特性其实目前是无法在自己的程序中去理解,而是需要在特定情况下去使用。因此目前我会尽量结合一些特定的代码去理解,当然这种可能看似没有意义的代码不一定真没有意义,而是并非特定的使用场景。


再谈构造函数

        在前面的文章中我们提到,构造函数其实就是一种特殊的成员函数,用于在类进行定义的时候直接初始化。我们不去单独构造它,编译器会默认给类自定义类型的成员进行初始化。

        而今天我们提到构造函数,其本质要实现的目的还是一样的,即在创建对象的时候,编译器调用其构造函数,给对象的每一个成员变量一个合适的初始值。

class Date
{
public:
	Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;
};

        上述的构造函数可以完成对创建对象赋值,但当这种属于赋予初始值,不能完成称之为初始化。为何这样子说,初始化的意义在于对变量进行赋予有价值的值,避免在后期调用出现随机值等情况影响程序的正常。构造函数体内部可以多次赋值,这本质还不算是真正意义上的初始化。

初始化只初始化一次,即在对象定义的时候就得初始化。那么我们来看下面的一段代码。

const int j;       ❌
const int j = 0;   ✅

对于一个常量需要初始化,有且只有一次机会,且必须初始化。那么针对于这真情况,我们怎么做才能对常量初始化呢。

class Date
{
public:
	Date(int year, int month, int day,const int N)
	{
		_year = year;
		_month = month;
		_day = day;
	}
private:
	int _year;
	int _month;
	int _day;

	const int _N = 1;//❌
};
 

        这好比在图纸上搭建房子,要知道类里面都是声明呀,声明可以是初始化么?答案肯定是不可以的。初始化一个变量或者一个常变量,是要先拿到它的内存空间的,而_N显然只是声明出来而未定义!

        那么在构造函数内部给值么?

0ab53d9a56c2440099dc4d2a0224ed47.png

        编译器不仅diss你没有完成初始化设定项,还提醒你表达式必须是可以修改的左值。这意味什么! _N在构造函数内部就已经定义了,而现在又改不了它的值了。

       祖师爷通过类和对象的思想进行封装是好事儿,构造函数也很棒,但牵一发而动全身,作为成员变量又不能在外部去定义,在内部构造函数内部构造函数又拿它没办法。因此,就需要来一个新特性来解决这个问题,就和说慌一样,说一个慌就需要用很多慌去圆。

初始化列表 

        初始化列表:以一个冒号开始,接着睡一个一逗号分隔的数据成员列表,每个成员变量的后面跟着一个放在括号中的初始值或者表达值。

class Date
{
public:
	Date(int year, int month, int day)
		:_year(year) //冒号开始
		,_month(month) //逗号分隔
		,_day(day) //()内部为初始化值
		,_N(1)
	{};
private:
	int _year;
	int _month;
	int _day;

	const int _N;//
};

        初始化列表是这些成员变量定义的地方,这里就相当于在定义的时候就初始化了。终于解决了常变量这个麻烦事儿,当然对于麻烦的事情不仅可以一起处理,也可以分开去处理。

e4a3c75cebf94ad783bfc3966685affe.png

 ⚠️注意:

  • 每一个成员变量在初始化列表中只能出现一次(初始化只初始化一次)

273794af4ff2449a8e90af3912b18eb6.png

  • 类中包含以下成员的时候必须放在初始化列表进行初始化
    • 引用成员变量        int& _ret;                                                           
    • const成员变量       const int _N;                                                     
    • 自定义成员变量(且该类没有构造函数的时候)      A   _aa;           
  • 尽量使用初始化列表进行初始化,因为不管你是否使用初始化列表,对于自定义类型成员变量,一定会先使用初始化列表初始化

        观察下述代码,Date创建一个对象其本身并没有使用Time _t的成员变量,但是对于自定义类型的成员变了,一定会先使用初始化列表进行初始化。

8539dfb89dce423695ac4c04d21ec378.png

  • 成员变量在类中的声明次序就是其在初始化列表的初始化顺序,与初始化列表中的前后次序无关

f50a4bee8fae48479cd66de80f54a5e2.png

        在类中声明的顺序是先_a2,后_a1,因此在进行初始化时候,先对_a进行初始化,此时_a1未初始化,为随机值,_a2就初始化了为这个随机值。_a1后初始化,接受了参数1,因此初始化了为1。

        当然对于初始化列表的顺序最好要和声明顺序一样,不然出现情况了不能老是弯弯绕绕的分析吧!

explicit关键字

观察下面的代码:

class Date {
public:
	Date(int year)
		: _year(year)
	{
		;
	}
	void Printf()
	{
		cout << _year << endl;
	}

private:
	int _year;
};

int main(void)
{
	Date d1(2022);
	cout << "d1-> ";
	d1.Printf();
	Date d2 = 2022;    // 隐式类型转换
	cout << "d2-> ";
	d2.Printf();

	return 0;
}

dd68de240dd34cbea33469cd626b2bec.png

        d1没什么好说的,可是d2就有点奇怪了,用一个整形值给d2赋值竟然可以赋值成功。其实这里就发生了隐式类型转换。实际上编译器会用2022这个值构造一个无名对象,最后将无名赋值给d1。这种隐式类型转换是存在的,且在单参数和多参数其第一个参数无缺省值(后两位可以不传参),而其他位均有缺省值得情况下就会发生这些默认的隐式类型转换。这样就会导致代码的可读性变差。因此 explicit 能修饰函数,限制其类型转换作用的发生。

909f4ef1ce6e4007967cda2d384005bc.png

static成员

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

        概念不好理解这里我们先来试着写一段代码,来体会一下何为静态成员和静态成员函数。

        现在,我们需要计算我们到底创建了多少个对象。这个很简单,即在所有构造函数内部实现对一个变量的加减即可,如果要计算有多少个对象正被使用也只需要在析构函数对一个变量减值即可

       思路简单,问题来了,变量设置在哪里呢?

       我们设置为全局变量

int N = 0;  // 全局变量计数器
class A {
public:
	A(int a = 0)
		: _a(a) 
	{
		N++;
	}
	A(const A& aa)
		: _a(aa._a) 
	{
		N++;
	}
private:
	int _a;
};
void f(A a)
{
	;
}
int main(void)
{
	A a1;
	A a2 = 1;
	f(a1);
	cout << N << endl;
	return 0;
}

        这一段代码一定可以实现记数功能的,没错!笃定切肯定!但是类和对象核心就是封装,就设置一个变量N,随便外部都可以通过修改全局变量就能改变变量N,怎么能保证功能安全呢。

5ef1ab43224840f185fa79f7c6914138.png

        我们设置为成员变量,然后问题又来了。

class A {
public:
	A(int a = 0)
		: _a(a) {
		_N++;
	}
	A(const A& aa)
		: _a(aa._a) {
		_N++;
	}

private:
	int _a;
	int _N = 0;  
};

        对于上面的成员变量,每一次创建对象是使用的同一个_N吗?很显然不是,且每一个对象都是使用的this->_N,这就说明没一个对象都有一个_N,这种方案直接否定。还不如上一种全局变量呢,至少还能实现。 因此方案三出来了,static成员函数。

静态成员为所有类共享,不属于某个具体的类,存放在静态区。

class A {
public:
	A(int a = 0)
		: _a(a) {
		_N++;
	}
	A(const A& aa)
		: _a(aa._a) {
		_N++;
	}

//private:
	int _a;
	static int _N;  
};
int A::_N = 0;

        当然解决一个问题又来一个,静态成员首先也是一个成员,受public、protected、private访问限定符的限制。

        因此,对于一个静态成员的访问我们需要怎么样去访问呢?如果它是类的公有成员还好说,直接突破类域即可(即非private)。


int main(void)
{
	A a1;
	A a2 = 1;
	f(a1);
 
	cout << A::_sCount  << endl;  //突破类域进行访问
 
	//这里a1.并非在a1里面,静态成员为所有对象共享,这里只是帮助他突破类域的一种手段 
	cout << a1._sCount << endl;
	cout << a2._sCount << endl;
 
	return 0;

        如果不是公有成员呢,我们是否可以达到这种的目的呢。肯定也是可以的,通过在类内部设置一个Get_N()公有函数拿到这个值就好了。这个时候外部调用对象函数就能得到它了。

静态成员函数

类外调用该函数可以访问到,而静态成员函数就可以不使用对象就可以访问到它。

static int GetCount() 
​​​​​​​{
    return _sCount;
}

静态成员特性总结

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

友元

        何为友元,即作为一个类外部的函数或者类,能访问其friend声明所在类的一种方式。

d06f11d9a7ed458f85089e3811d1a8d0.png

 

        我们之前学了操作符重载,对与一个日期类,我们是否也可以通过重载operator<<和operator>>实现对日期类的流提取和流输入呢?

        我们先看流输入和流输出的库函数。

96def4c85df443f98958985c4bc4ca3b.png

3af60dcd3d1c4e3f81827e813b5265a8.png

        根据函数的原理和返回类型,我们直接开始我们的输入输出流重载。不懂原理目前也没事,可以知道的是cout和cin返回值类型是ostream和sitream。

ae4aa397110742bab4710ff53f0967cf.png

class Date
{
public:
	Date(int year = 1970, int month = 1, int day = 1)
		:_year(year)
		, _month(month)
		, _day(day)
	{};
	ostream& operator<<(ostream& _cout)
	{
		_cout << _year << "-" << _month << "-" << _day << endl;
		return _cout;
	}

private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	Date d1(2023, 4, 22);
	cout << d1;//无法识别
	return 0;
}

437a89964e8d4cd1959bc1e2b964a0c5.png        这里依旧识别不了,双操作数的运算符重载时,规定第一个参数是左操作数,第二个参数是右操作数。而这里悄咪咪藏着一个this指针。

        因此调用的时候就不能就不能按这样子了,那怎么调用呢。

int main()
{
	Date d1(2023, 4, 22);
	/*cout << d1;*/
	d1.operator<<(cout);
	d1 << cout;
	return 0;
}

c0cf02bb5b4744b992a571006bdb1ee9.png这可不对劲,正常流输入是cout<<d1,这可怎么办才好。很显然我们要消除this指针的影响,同时还能访问其类的内部成员,而友元就可以做到这样子的事情。一步到位,既不像全局函数的访问权限受限制,还可以直接直接消除this指针

友元函数

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

        

class Date
{
	friend ostream& operator<<(ostream& _cout, const Date& d);
	friend istream& operator>>(istream& _cin,Date& d);
public:
	Date(int year= 1970, 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 << endl;
	return _cout;
}
istream& operator>>(istream& _cin, Date& d)//要修改,别加const
{
	_cin >> d._year >> d._month >> d._day;
	return _cin;
}

int main()
{
	Date d;
	cin >> d;
	cout << d;
	return 0;
}

⚠️注意:

  • 友元函数可访问类的私有和保护成员,但不是类的成员函数。(只是类的朋友)
  • 友元函数不能用const修饰
  • 友元函数可以类定义的任何地方声明,不受类访问限定符限制
  • 一个函数可以是多个类的友元函数
  • 友元函数的调用与普通函数的调用原理相同

友元类

  • 友元类的所有成员函数都是其friend友元所在声明类的友元函数,都可以访问另一个类的公有成员。
  • 友元的关系不能传递,若如果B是A的友元,C是B的友元,则不能说明C是A的友元。
  • 友元不能继承,关于继承的详细讲解在后面博客文章阐述,这里不展开讲解。

定义一个友元类

class Date;   // 前置声明
 
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 = 1970, int month = 1, int day = 1)
		: _year(year)
		, _month(month)
		, _day(day)
	{}
 
	void SetTimeOfDate(int hour, int minute, int second)
	{
		// 直接访问Time类私有的成员变量
		_t._hour = hour;
		_t._minute = minute;
		_t._second = second;
	}
 
private:
	int _year;
	int _month;
	int _day;
	Time _t;
};

d3dd2d3e8b4d4240b87443c4c075c2d8.png

        也就是说这种访问是单向的,时间类里不能访问日期类,因为这是 "单向好友",要想互相访问,只需要互相为各自的友元就好啦。

⚠️注意:

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

内部类

        内部类顾名思义就是一个类内部的类。即一个类如果定义在一个类的内部,这个类就叫做内部类。内部类是一个独立的类。它不属于外部内,更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任何优越的访问权限。

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

特性:

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

其实这里的概念我们结合友元类就能清晰理解,内部类是外部类的天生友元。

class A {
private:
	static int _s_a1;
	int _a2;
public:
	class B 
	{
		// B天生就是A的友元
	public:
		void foo(const A& a) 
		{
			cout << _s_a1 << endl;  
			cout << a._a2 << endl;  
		}
	private:
		int _b1;
	};
};

        但是需要着重理解的一点是,在写代码的时候看似是外部包含内部的关系,但是实际上以权限的角度来讲,内部权限大于外部,即内包外。要从权限这点抽象的去理解,而非看见的写代码时候的包含关系。

class A {
private:
    static int _s_a1; 
    int _a2;
 
public:
    class B {  // B天生就是A的友元
        friend class A;  // 声明A是B的友元
    private:
        int _b1;
    };
};

我们也可以通过以上的方式去实现打破这种封装,不过情况很少,既然这样子为何不使用一个类呢(除非特定情况)。

再度理解类和对象

        类和对象是面向对象编程(Object-Oriented Programming,简称OOP)中的两个重要概念,用于组织和管理代码,使其更易于理解、维护和扩展。

        类(Class) 可以看作是一张图纸或模板。假设你要建造一栋房子,你需要一张建筑图纸来指导建筑师和工程师。这张图纸就像一个类,它包含了房子的设计、规格和特点。图纸上可能包括了房子的形状、大小、门窗的位置等信息,就像一个类包含属性和方法的定义。

        对象(Object) 则就是按照那张图纸建造出来的实际房子。当你按照图纸建造房子时,你实际上是在基础上创建了一个具体的、独立的实体。这个实际的房子就像类的对象,它有自己的属性(如颜色、材料、装饰)和可以执行的操作(如打开门、关上窗户),但它们都基于同一张图纸创建。

        举个更具体的例子,想象一个类是"汽车",它的属性包括颜色、品牌和速度,方法包括启动、加速和刹车。当你购买一辆具体的车,比如一辆红色的福特(Ford),你就得到了一个对象,这个对象就是这个类的一个实例,拥有红色的颜色、福特的品牌,以及能够启动、加速和刹车等方法。

        所以,类就像是一个设计图纸,对象就像是根据这个图纸建造出来的实际物体。图纸定义了如何制造物体,而物体是根据图纸的规格制造的。类定义了对象的结构和行为,而对象则是类的具体实例,具有自己的属性值,可以执行类中定义的方法。这是面向对象编程的核心概念之一,它有助于将代码组织成更加模块化、可维护和可重用的部分。


总结

在C++类和对象的三个篇章中,主要涉及了C++中类和对象的一系列知识点,包括:

  1. 构造函数和析构函数

  2. 拷贝构造函数

  3. 赋值运算符重载

  4. const成员函数

  5. 初始化列表

  6. static成员

  7. 友元函数和友元类

  8. 内部类

        在本篇文章中,完结了关于C++类和对象的重要知识点。类和对象是面向对象编程的核心,通过构造函数、析构函数、拷贝构造函数等,我们可以创建对象并初始化其属性。静态成员允许类级别的属性和方法,友元函数和友元类提供了访问私有成员的机制,而内部类允许在类内部定义嵌套的类。

        这些知识点为理解和应用C++中的面向对象编程提供了基础。虽然这些概念可能看起来复杂,但它们有助于将代码组织成更模块化、可维护和可重用的部分。相信大家通过不断学习和实践,可以更好地掌握C++编程的技能,并编写更高效、可维护的代码。


    作者水平有限,如有错误欢迎指正!


9b1eda4aca3b477491f9b5366a7d2204.gif

 

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

解决方案|法大大电子合同加速互联网家装服务升级

随着互联网的快速发展以及政策的不断推动&#xff0c;家装行业“互联网”趋势也不断凸显。行业内很多企业已经开始在全链条业务中使用电子合同&#xff0c;基于电子合同合规化、无纸化、线上化、智能化的价值赋能&#xff0c;实现家装从需求沟通、家装设计、选材、装修施工、验…

【MySQL--->内外连接】

文章目录 [TOC](文章目录) 一、内连接二、左外连接三、右外连接 一、内连接 内连接就是将两个表连接进行笛卡尔积查询 显示SMITH的名字和部门名称 二、左外连接 左外连接就是以左面的表为主&#xff0c;即便是右边的表没有而左边表项中有的&#xff0c;依然显示 查询所有学…

jenkins详细安装教程

这里写目录标题 一、Jenkins安装与部署1-1、Jenkins的简介1-2、下载需要的软件1-2-1 jekins.war1-2-2 tomcat安装方式 1-3、使用11版本的jdk1-4、开启jenkins1-5、获取密码1-5 修改镜像(可改可不改) 二、卸载Jenkins 一、Jenkins安装与部署 1-1、Jenkins的简介 Jenkins是一个…

Linux 基础入门

Linux 简介 Linux 是一种自由和开放源码的类 UNIX 操作系统。 Linux 英文解释为 Linux is not Unix。 Linux 是在 1991 由林纳斯托瓦兹在赫尔辛基大学上学时创立的&#xff0c;主要受到 Minix 和 Unix 思想的启发。 Linux 内核最初只是由芬兰人林纳斯托瓦兹&#xff08;Linus T…

基于SSM的n省出口基地公共信息服务平台设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

Spring Cloud Gateway + Knife4j 4.3 实现微服务网关聚合接口文档

目录 前言Spring Cloud 整合 Knife4jpom.xmlapplication.ymlSwaggerConfig.java访问单服务接口文档 Spring Cloud Gateway 网关聚合pom.xmlapplication.yml访问网关聚合接口文档 接口测试登录认证获取登录用户信息 结语源码 前言 youlai-mall 开源微服务商城新版本基于 Spring…

评估在线不平衡学习的PAUC

评估在线不平衡学习的PAUC 原始论文《Prequential AUC: properties of the area under the ROC curve for data streams with concept drift》 由于正常的AUC需要计算整体数据集上&#xff0c;每个数据的预测置信度的排名。那么我们首先要求我们的在线学习算法在进行预测时也返…

node实战——后端koa结合jwt连接mysql实现权限登录(node后端就业储备知识)

文章目录 ⭐前言⭐ 环境准备⭐ 实现过程⭐ mysql 配置⭐路由前的准备⭐账号注册生成token⭐账号登录生成token⭐token登录 ⭐ 自测过程截图⭐总结⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本文分享关于node实战——后端koa项目配置jwt实现登录注册&#xff08;n…

博客模板博客模板

xservices-bpm-6.2.1.1.jar 本人详解 作者&#xff1a;王文峰&#xff0c;参加过 CSDN 2020年度博客之星&#xff0c;《Java王大师王天师》作者 公众号&#xff1a;山峯草堂&#xff0c;非技术多篇文章&#xff0c;专注于天道酬勤的 Java 开发问题、中国国学、传统文化和代码爱…

智慧矿山AI算法助力护帮板支护监测,提升安全与效率

在智慧矿山AI算法系列中&#xff0c;护帮板支护监测是保障矿山安全和提高生产效率的重要环节。护帮板作为矿山支护体系中的重要组成部分&#xff0c;在矿山生产中起到了关键的作用。那么&#xff0c;护帮板在哪种状态下是正常打开的呢&#xff1f;本文将对此进行介绍。 护帮板的…

LeetCode热题100 240.搜索二维矩阵||

题目描述&#xff1a; 编写一个高效的算法来搜索 m*n 矩阵 matrix 中的一个目标值 target 。该矩阵具有以下特性&#xff1a; 每行的元素从左到右升序排列。每列的元素从上到下升序排列。 示例1&#xff1a; 输入&#xff1a;matrix [[1,4,7,11,15],[2,5,8,12,19],[3,6,9,16,2…

「实验记录」CS144 Lab0 networking warmup

文章目录 一、Motivation二、SolutionsS1 - Writing webgetS2 - An in-memory reliable byte stream 三、Results四、Source 一、Motivation 第一个小测试 webget 是想让我们体验并模拟一下在浏览器中键入 URL 后获得远程服务器传来的内容&#xff0c;这并没有太大的难度&…

【IDEA】设置sql提示

第一步&#xff1a;注入SQL语言 1.首先选择任意一条sql语句&#xff0c;右击&#xff0c;选择 ‘显示上下文操作’ 2.选择 ‘注入语言或引用’ 3. 往下翻&#xff0c;找到MySQL 第二步&#xff1a;配置MySQL数据库连接 1.首先点击侧边的数据库&#xff0c;再点击上面的加号 2…

OpenCV官方教程中文版 —— Hough 圆环变换

OpenCV官方教程中文版 —— Hough 圆环变换 前言Hough 圆环变换 前言 目标 • 学习使用霍夫变换在图像中找圆形&#xff08;环&#xff09; • 学习函数&#xff1a;cv2.HoughCircles() Hough 圆环变换 opencv_logo.png&#xff1a; # -*- coding: utf-8 -*- import cv2 …

基于STC12C5A60S2系列1T 8051单片机可编程计数阵列CCP/PCA/PWM模块的PWM(脉冲宽度调制)应用

基于STC12C5A60S2系列1T 8051单片机可编程计数阵列CCP/PCA/PWM模块的PWM&#xff08;脉冲宽度调制&#xff09;应用 STC12C5A60S2系列1T 8051单片机管脚图STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式及配置STC12C5A60S2系列1T 8051单片机I/O口各种不同工作模式介绍STC…

设备完全有效生产率TEEP对生产制造企业有什么作用?

设备完全有效生产率&#xff08;Total Effective Efficiency of Production&#xff0c;简称TEEP&#xff09;是反映企业设备效率的一项重要指标&#xff0c;用于评估生产制造企业的设备利用率和生产效率。本文将从三个方面探讨TEEP的含义、计算方法以及对生产制造企业的作用。…

回收废品抢派单小程序开源版开发

回收废品派单抢派单小程序开源版开发 在这个废品回收抢单派单小程序开源版开发中&#xff0c;我们将构建一个专业且富有趣味性的平台&#xff0c;以深度的模式来重塑废品回收体验。 我们将提供一个会员注册功能&#xff0c;用户可以通过小程序授权注册和手机号注册两种方式快…

Leetcode—2558.从数量最多的堆取走礼物【简单】

2023每日刷题&#xff08;十二&#xff09; Leetcode—2558.从数量最多的堆取走礼物 大顶堆实现代码 void swap(int *a, int *b) {int tmp *a;*a *b;*b tmp; }void downAdjustHeap(int *heap, int low, int high) {int i low;int j 2 * i 1;while(j < high) {if(j …

气膜场馆里面噪声很大怎么解决?

随着气膜结构在各个领域的广泛应用&#xff0c;人们开始意识到在这些场馆内部&#xff0c;特别是在大型活动和展览中&#xff0c;噪声问题可能会变得相当严重。传统的气膜结构通常难以提供良好的声学环境&#xff0c;这对于参与者的舒适度和活动的质量构成了挑战。为了解决气膜…

国外怎么传大文件到国内,这款传输软件跨国企业必备

从国外传输文件到国内&#xff0c;这项任务常常充满了挑战。国际之间的距离、网络延迟、数据安全和文件大小限制等问题使得这个过程异常复杂。本文将深入剖析这些挑战&#xff0c;并说明一款优秀的跨国传输软件&#xff0c;如何能够成为解决这些问题的强有力工具。 国外传输文件…