【C++】类与对象 第二篇(构造函数,析构函数,拷贝构造,赋值重载)

目录

类的6个默认成员函数

初始化和清理

1.构造函数

2.析构函数

3.共同点

拷贝复制

1.拷贝构造

使用细节

2.赋值重载

运算符重载

== <= < >= > !=

连续赋值


C++入门 第一篇(C++关键字, 命名空间,C++输入&输出)-CSDN博客

C++入门 第二篇( 引用、内联函数、auto关键字、指针空值nullptr)-CSDN博客

【C++】类与对象 第一篇(class,this)-CSDN博客

类的6个默认成员函数

默认成员函数:用户没有显式实现,编译器会生成的成员函数称为默认成员函数。

初始化和清理

1.构造函数

特征: 构造函数是特殊的成员函数,需要注意的是,构造函数虽然名称叫构造,但是构造函数的主要任 务并不是开空间创建对象,而是初始化对象其特征如下:

  1. 函数名与类名相同。

  2. 无返回值。

  3. 对象实例化时编译器自动调用对应的构造函数。

  4. 构造函数可以重载。

 class Stack{public:Stack(){_a=nullptr;_size=_capacity=0;}​Stack(int n){_a=(int*)malloc(sizeof(int)*n);_size=_capacity=0;}​void Init(int n=4){_a=(int*)malloc(sizeof(int)*n);if (nullptr==_a){perror("malloc is fail");return;}_capacity=n;_size=0;}​void Push(int x){//...a[_size++]=x;}//...void Dstory(){//...}​private:int _a;int _size;int _capacity;};​int main(){Stack st;//无参//Stack st();//有参​st.Push(1);st.Push(2);st.Push(3);st.Push(4);​st.Dstory();​return 0;}

以上述代码为例:

自动调用初始化

注意:调用无参时如:Data d;此处在后面不能➕(),否则编译器会调用有参的。

使用缺省值:

 class Date{public:Date(int year=1,int month=1,int day=1){_year=1;_month=1;_day=1;}​void print(){cout<<_year<<"/"<<_month<<"/"<<_day<<endl;}​private://成员变量int _year;int _month;int _day;};​int main(){//Date d1;Date d2(2077,2,3);d2.print();​return 0;}

2.析构函数

概念: 通过前面构造函数的学习,我们知道一个对象是怎么来的,那一个对象又是怎么没呢的? 析构函数:与构造函数功能相反,析构函数不是完成对对象本身的销毁,局部对象销毁工作是由 编译器完成的。而对象在销毁时会自动调用析构函数,完成对象中资源的清理工作

特性 析构函数是特殊的成员函数,其特征如下:

  1. 析构函数名是在类名前加上字符 ~

  2. 无参数无返回值类型。

  3. 一个类只能有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。注意:析构 函数不能重载

  4. 对象生命周期结束时,C++编译系统系统自动调用析构函数。

例子:

 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);}

3.共同点

如果编译过程不写,那编译器会自动生成一个默认的,但是如果我们实现了任意一个,编译器就不会生成了。

若是自动初始化,那为什么这个地方会生成随机值呢?

C++把类型分成内置类型(基本类型)自定义类型。内置类型就是语言提供的数据类 型,如:int/char...,自定义类型就是我们使用class/struct/union等自己定义的类型,看看 下面的程序,就会发现编译器生成默认的构造函数会对自定类型成员_t调用的它的默认成员 函数。

内置类型(基本类型):int/char/double... /任意类型指针 自定义类型:class/structd定义的

默认生成构造函数:

1.内置类型成员不做处理。

2.自定义类型的成员,会去调用它的默认构造(不用传参数的构造)

 private:// 基本类型/内置类型 - 不进初始化int _year;int _month;int _day;

实用场景:

 class Date{public://内置类型成员不做处理void print(){cout<<_year<<"/"<<_month<<"/"<<_day<<endl;}​private:// 基本类型/内置类型 - 不进初始化int _year;int _month;int _day;};​class MyQueue{// 默认生成构造函数,对自定义类型,会调用它的默认构造函数void push(int x);{​}//...Stack _pushST();Stack _popST();};

析构:

默认生成构造函数:

1.内置类型成员不做处理。

2.自定义类型的成员,会去调用它的析构函数

 class MyQueue{// 默认生成析构函数,对自定义类型,会调用它的析构函数void push(int x);{​}Stack _pushST();Stack _popST();};​int main(){//Date d1;Date d1;d1.print();​MyQueue q;​return 0;}

内置类型并不会主动初始化,但可以通过给缺省值进行初始化:

 private://声明位置给缺省值int _year=1;int _month=1;int _day=1;

无参的构造函数和全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个。 注意:无参构造函数全缺省构造函数、我们没写编译器默认生成的构造函数,都可以认为 是默认构造函数。

拷贝复制

1.拷贝构造

拷贝构造函数:只有单个形参,该形参是对本类类型对象的引用(一般常用const修饰),在用已存 在的类类型对象创建新对象时由编译器自动调用

拷贝构造:内置类型,编译器直接拷贝,自定义类型拷贝需要调用拷贝构造

特征

拷贝构造函数也是特殊的成员函数,其特征如下:

  1. 拷贝构造函数是构造函数的一个重载形式

    为什么自定义类型要用拷贝构造,而内置类型编译器却可以直接拷贝(按字节拷贝)? ​ 因为自定义类型进行拷贝容易出问题:若要拷贝栈,栈的成员变量都是指向相同的空间,若进行拷贝,则会导致两个Stack指向同一个空间,导致原本Stack执行析构函数时被销毁,而复制的那个则指向空,正确的应该是各有各的空间。

  2. 拷贝构造函数的参数只有一个必须是类类型对象的引用,使用传值方式编译器直接报错, 因为会引发无穷递归调用。

class Date{public:Date(int year=2077, int month=10, int day=12){_year = year;_month = month;_day = day;}Date(Date d)//这样拷贝会造成无限递归{_year = d.year;_month = d.month;_day = d.day;}​private:int _year;int _month;int _day;};

在拷贝构造函数 Date(Date d) 中,参数 d 是按值传递的,这意味着每次调用拷贝构造函数时都会创建一个新的 Date 对象,并将原始对象 d 复制到新的对象中。然而,在拷贝构造函数内部,对于拷贝构造函数的调用又会传递同样的参数 d,导致不断地递归调用拷贝构造函数,从而产生无限递归。

则可以使用 & ,使其不在重新创建空间并使用原Date对象

Date(const Date& d){_year = d._year;_month = d._month;_day = d._day;}

这个拷贝构造函数将创建一个新的 Date 对象,并将原始对象的 _year_month_day 成员变量的值分别拷贝到新对象的相应成员变量中。通过使用对象引用作为参数,我们可以避免无限递归调用拷贝构造函数的问题,并且确保在构造新对象时不会复制整个对象

 
class Date{public:Date(int year = 2077, int month = 10, int day = 12){_year = year;_month = month;_day = day;}​Date(const Date& d)//const是为了防止写反->d._year = _year;加const缩小权限{cout<<"Date(Date& d);"<<endl;_year = d._year;_month = d._month;_day = d._day;}​private:int _year;int _month;int _day;};​int main(){Date d1(2023, 2, 3);//两种拷贝方式Date d2(d1); // 使用拷贝构造函数创建对象 d2,并将 d1 的值拷贝到 d2 中Date d3=d1;​return 0;}

RunCode:

若未显式定义,编译器会生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按 字节序完成拷贝,这种拷贝叫做浅拷贝,或者值拷贝。

深拷贝是指在对象拷贝时,复制所有的数据和资源,使得新对象和原对象完全独立,互不影响。与之相对的是浅拷贝,浅拷贝只复制指针或引用,导致新旧对象共享同一份数据,修改一个可能会影响另一个。深拷贝能够保证对象之间的独立性和数据完整性。

分清楚是不是拷贝构造:

 class Date{public:Date(int year = 2077, int month = 10, int day = 12){_year = year;_month = month;_day = day;}//拷贝构造函数   Date(const Date& d){cout<<"Date(Date& d);"<<endl;_year = d._year;_month = d._month;_day = d._day;}​//构造函数 不是拷贝构造Date(const Date* d){cout<<"Date(Date& d);"<<endl;_year = d._year;_month = d._month;_day = d._day;}private:int _year;int _month;int _day;};​int main(){Date d1(2023, 2, 3);//Date(const Date* d)Date d2(&d1); Date d3=&d1;​return 0;}

拷贝构造函数典型调用场景:

  • 使用已存在对象创建新对象

  • 函数参数类型为类类型对象

  • 函数返回值类型为类类型对象

使用细节

1使用拷贝构造时最好加上const,以防权限的放大

   // 拷贝构造Date(const Date &d){_year = d.year;_month = d.month;_year = d.year;}

2编译器可自动生成但存在问题

本文所用的日期类可以使用自动生成拷贝,但进行拷贝栈时就会出现问题

当进行拷贝时,用值拷贝,导致两个栈指向同一个空间,造成空间互相覆盖 指向同一块空间的问题:1.插入删除数据会互相影响 2.析构两次,程序崩溃

析构是也跟栈一样是后进先出后定义的先析构,故st2先析构,对st2滞空是,并不影响st1,导致野指针。此时浅拷贝行不通,需要进行深拷贝:

代码实现:

class Stack{public:void Push(const int &data){_array[_size] = data;_size++;}​Stack(const Stack &st){_array = (int *)malloc(sizeof(int) * st._capacity);if (nullptr == _array){perror("malloc is fail");exit(-1);}memcpy(_array, st._array, sizeof(int) * st._size);_size = st._size;_capacity = st._capacity;}​~Stack(){if (_array){delete[] _array;_array = nullptr;_capacity = 0;_size = 0;}}​private:int *_array;int _size;int _capacity;};​int main(){Stack st1;st1.Push(1);st1.Push(2);st1.Push(3);​Stack st2(st1);​return 0;}

什么情况下需要事项拷贝构造呢? 自己实现了析构释放空间,就需要实现拷贝构造

 class Stack{public://构造函数  Stack(size_t _capacity = 10){cout << "Stack(size_t _capacity)" << endl;_array = (int *)malloc(sizeof(int) * _capacity);if (nullptr == _array){perror("malloc is fail");exit(-1);}_size = 0;_capacity = _capacity;}​void Push(const int &data){_array[_size] = data;_size++;}​//拷贝构造Stack(const Stack &st){_array = (int *)malloc(sizeof(int) * st._capacity);if (nullptr == _array){perror("malloc is fail");exit(-1);}memcpy(_array, st._array, sizeof(int) * st._size);_size = st._size;_capacity = st._capacity;}​~Stack(){if (_array){delete[] _array;_array = nullptr;_capacity = 0;_size = 0;}}​private:int *_array;int _size;int _capacity;};​class MyQueue{//默认生成构造 ->生成定义在Stack中的默认构造函数//默认生成析构//默认生成的拷贝构造private:Stack _pushST;Stack _popST;int _size = 0;};​int main(){Stack st1;st1.Push(1);st1.Push(2);st1.Push(3);​Stack st2(st1);cout<<"====="<<endl;MyQueue q;​return 0;}

默认生成拷贝构造和赋值重载:

a.内置类型完成 浅/值 拷贝--按byte一个一个拷贝

b.自定义类型,去调用这个成员 拷贝构造/赋值重载

2.赋值重载

运算符重载

C++为了增强代码的可读性引入了运算符重载运算符重载是具有特殊函数名的函数,也具有其 返回值类型,函数名字以及参数列表,其返回值类型与参数列表与普通的函数类似。

函数名字为:关键字operator后面接需要重载的运算符符号。 函数原型:返回值类型 operator操作符(参数列表)

自定义类型不能直接使用运算操作符 内置类型是语法定义,而自定义类型为人为定义,编译器并不知道该如何进行比较,这便出现了operator用函数完成

运算符重载:自定义类型对象可以使用运算符

函数重载:支持函数名相同,参数不同的函数

 
#include <iostream>using namespace std;​class Date{public:// 构造函数Date(int year = 1, int month = 1, int day = 1){_year = year;_month = month;_day = day;}​// 拷贝构造Date(const Date &d){_year = d._year;_month = d._month;_day = d._day;}​void Print(){cout << _year << "/" << _month << "/" << _day << endl;}​// d1==d2 -> d1.operator==(d2)bool operator==(const Date &d){return _year == d._year && _month == d._month && _day == d._day;//    this->_year==d.year}​private:// 成员变量int _year;int _month;int _day;};​int main(){Date d1(2077, 2, 4);Date d2(2077, 2, 4);​// d1==d2;cout << d1.operator==(d2) << endl;cout << (d1 == d2) << endl;​return 0;}

注意:

  • 不能通过连接其他符号来创建新的操作符:比如operator

  • 重载操作符必须有一个类类型参数

  • 用于内置类型的运算符,其含义不能改变,例如:内置的整型+,不能改变其含义

  • 作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐 藏的this现。

  • 注意以下5个运算符不能重载

     .*   ::  sizeof  ?:   .

== <= < >= > !=
// d1==d2 -> d1.operator==(d2)bool operator==(const Date &d){return _year == d._year && _month == d._month && _day == d._day;//    this->_year==d.year}​// 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;//     }//     else//         return false;// }​// d1<d2bool operator<(const Date &d){return _year < d._year && (_year == d._year && _month < d._month) && (_year == d._year && _month == d._month && _day < d._day);}

任何一个类都适用于,当写了一个>=或<=那其他的就可以进行复用

     // d1<=d2bool operator<=(const Date &d){return *this < d || *this == d;//*this就是d1}

这个地方对operator<(const Date &d)进行了复用。operator<=(const Date &d)中的表达式*this < d调用了operator<(const Date &d)来判断两个日期对象的大小关系。同时,operator<=(const Date &d)还利用operator==(const Date &d)来判断两个日期对象是否相等。通过这样的复用方式,可以简化代码并提高代码的可读性

     // d1>d2bool operator>(const Date &d){return !(*this<= d);}​//d1>=d2bool operator>=(const Date& d){return !(*this<d);}​//d1!=d2bool operator!=(const Date& d){return !(*this ==d);}

当然赋值运算符不使用&并不会无限循环

    // d1<=d2bool operator<=(const Date d){return *this < d || *this == d;}

当然可以不用,但是最好还是加上

连续赋值

d3 = d1 = d2

     // 因为Date operator=(const Date &d) 出了该函数的作用域*this/d1 还在此时返回的*this是临时拷贝,需要进行拷贝重新开空间造成浪费,不如直接进行&Date operator=(const Date &d)//&d 引用{if (this != &d)//防止d1=d1进行赋值 此处的&为去地址 ,若this与d的地址一样则无需赋值{_year = d._year;_month = d._month;_day = d._day;}​return *this; //*this就是d1}                 // 返回值为了支持连续赋值,保持运算符特性  d3=d1=d2;

当然要注意,赋值重载是针对已经创造的对象

 Date d5=d1;//拷贝构造

像这样就是拷贝构造

同样作为默认成员函数,可以不用手动写

源码:

 #include <iostream>using namespace std;​class Date{public:// 构造函数Date(int year = 1, int month = 1, int day = 1){_year = year;_month = month;_day = day;}​// 拷贝构造Date(const Date &d){_year = d._year;_month = d._month;_day = d._day;}​void Print(){cout << _year << "/" << _month << "/" << _day << endl;}// d1==d2 -> d1.operator==(d2)bool operator==(const Date &d){return _year == d._year && _month == d._month && _day == d._day;//    this->_year==d.year}​// d1<d2bool operator<(const Date &d){return _year < d._year && (_year == d._year && _month < d._month) && (_year == d._year && _month == d._month && _day < d._day);}​// d1<=d2bool operator<=(const Date &d){return *this < d || *this == d; //*this就是d1}​// d1>d2bool operator>(const Date &d){return !(*this <= d);}​// d1>=d2bool operator>=(const Date &d){return !(*this < d);}​// d1!=d2bool operator!=(const Date &d){return !(*this == d);}​// // 因为Date operator=(const Date &d) 出了该函数的作用域*this/d1 还在此时返回的*this是临时拷贝,需要进行拷贝重新开空间造成浪费,不如直接进行&// Date operator=(const Date &d)//&d 引用// {//     if (this != &d)//防止d1=d1进行赋值 此处的&为去地址 ,若this与d的地址一样则无需赋值//     {//         _year = d._year;//         _month = d._month;//         _day = d._day;//     }​//     return *this; //*this就是d1// }                 // 返回值为了支持连续赋值,保持运算符特性  d3=d1=d2;​private:// 成员变量int _year;int _month;int _day;};​int main(){Date d1(2077, 2, 4);Date d2(2222, 3, 2);Date d3(2078, 2, 4);​cout << (d1 < d2) << endl;// d3 = d1 = d2;​d1 = d2;d1.Print();​return 0;}

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

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

相关文章

【开源】基于SpringBoot的海南旅游景点推荐系统的设计和实现

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 用户端2.2 管理员端 三、系统展示四、核心代码4.1 随机景点推荐4.2 景点评价4.3 协同推荐算法4.4 网站登录4.5 查询景点美食 五、免责说明 一、摘要 1.1 项目介绍 基于VueSpringBootMySQL的海南旅游推荐系统&#xff…

2017年上半年上午易错题(软件设计师考试)

CPU 执行算术运算或者逻辑运算时&#xff0c;常将源操作数和结果暂存在&#xff08; &#xff09;中。 A &#xff0e; 程序计数器 (PC) B. 累加器 (AC) C. 指令寄存器 (IR) D. 地址寄存器 (AR) 某系统由下图所示的冗余部件构成。若每个部件的千小时可靠度都为 R &…

如何使用手机蓝牙设备作为电脑的解锁工具像动态锁那样,蓝牙接近了电脑,电脑自动解锁无需输入开机密码

环境&#xff1a; Win10 专业版 远程解锁 蓝牙解锁小程序 问题描述&#xff1a; 如何使用手机蓝牙设备作为电脑的解锁工具像动态锁那样&#xff0c;蓝牙接近了电脑&#xff0c;电脑自动解锁无需输入开机密码 手机不需要拿出来&#xff0c;在口袋里就可以自动解锁&#xff…

C#,数值计算——分类与推理,基座向量机的 Svmgenkernel的计算方法与源程序

1 文本格式 using System; namespace Legalsoft.Truffer { public abstract class Svmgenkernel { public int m { get; set; } public int kcalls { get; set; } public double[,] ker { get; set; } public double[] y { get; set…

机器学习-特征选择:如何使用互信息特征选择挑选出最佳特征?

一、引言 特征选择在机器学习中扮演着至关重要的角色&#xff0c;它可以帮助我们从大量的特征中挑选出对目标变量具有最大预测能力的特征。互信息特征选择是一种常用的特征选择方法&#xff0c;它通过计算特征与目标变量之间的互信息来评估特征的重要性。 互信息是信息论中的一…

Csdn文章编写参考案例

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

cosover是什么?crossover23又是什么软件

cosover是篮球里的过人技巧。 1.crossover在篮球中的本意是交叉步和急速交叉步。crossover 是篮球术语&#xff0c;有胯下运球、双手交替运球&#xff0c;交叉步过人、急速大幅度变向等之意。 2.在NBA里是指包括胯下运球、变向、插花在内的过人的技巧。 NBA有很多著名的Cross…

Linux进程等待

一、进程等待是什么&#xff1f; 通过系统调用wait/waitpid&#xff0c;来对子进程进行状态检验与回收的工作。 二、为什么要有进程等待 1、子进程退出&#xff0c;父进程如果不管不顾&#xff0c;就可能造成‘僵尸进程’的问题&#xff0c;进而造成内存泄漏。 另外&#xf…

数据库分库分表的原则

目录 1、数据库分库分表是什么 2、为什么要对数据库分库分表 3、何时选择分库分表 4、⭐分库分表遵循的原则 5、分库分表的方式 6、数据存放在表和库中的规则&#xff08;算法&#xff09; 7、分库分表的架构模式 8、分库分表的问题 小结 1、数据库分库分表是什么 数…

不一样的网络协议-------KCP协议

1、kcp 的协议特点 1.1、RTO 不翻倍 RTO(Retransmission TimeOut)&#xff0c;重传超时时间。tcp x 2&#xff0c;kcp x 1.5&#xff0c;提高传输速度 1.2、选择重传 TCP丢包时会全部重传从该包开始以后的数据&#xff0c;而KCP选择性重传&#xff0c;只重传真正丢失的数据包…

基于单片机16位智能抢答器设计

**单片机设计介绍&#xff0c;1645【毕设课设】基于单片机16位智能抢答器设计&#xff08;裁判功能、LCD数码管显示&#xff09;汇编 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序程序文档 六、 文章目录 一 概要 基于单片机16位智能抢答器设计&#x…

json格式存储b64编码的rgb raw数据

1.rgb raw数据准备 利用python将jpg里面的rgb raw数据提取出来。 import cv2# 读取 JPG 图像 image_path 1.jpg image cv2.imread(image_path)#imread读出来的顺序是BGR print("image shape:",image.shape)# 将图像由BGR转换为 RGB 数据 rgb_data cv2.cvtColor(im…

C++单调向量算法应用:所有子数组中不平衡数字之和

涉及知识点 单调向量 题目 一个长度为 n 下标从 0 开始的整数数组 arr 的 不平衡数字 定义为&#xff0c;在 sarr sorted(arr) 数组中&#xff0c;满足以下条件的下标数目&#xff1a; 0 < i < n - 1 &#xff0c;和 sarr[i1] - sarr[i] > 1 这里&#xff0c;sort…

vivado窗口使用与分析2-IDE 中的逻辑分析

逻辑分析 包括 &#xff1a; • “ Netlist ”窗口 • “ Hierarchy ”窗口 • “ Schematic ”窗口 1、 “ Netlist ”窗口 “ Netlist ” &#xff08; 网表 &#xff09; 窗口显示了网表中由综合工具所处理的设计层级。 根据综合设置 &#xff0c; 网表层级与原始 RT…

buuctf_练[安洵杯 2019]easy_web

[安洵杯 2019]easy_web 文章目录 [安洵杯 2019]easy_web掌握知识解题思路代码分析正式解题 关键paylaod 掌握知识 url地址和源代码的信息捕捉&#xff1b;图片和base64之间转换&#xff1b;base64和十六进制编码的了解&#xff1b;代码审计&#xff0c;绕过正则匹配对关键字的…

Pytorch代码入门学习之分类任务(二):定义数据集

一、导包 import torch import torchvision import torchvision.transforms as transforms 二、下载数据集 2.1 代码展示 # 定义数据加载进来后的初始化操作&#xff1a; transform transforms.Compose([# 张量转换&#xff1a;transforms.ToTensor(),# 归一化操作&#x…

【Java网络原理】 四

本文主要介绍了TCP/IP五层协议中的应用层常见的数组组织格式和传输层UDP协议。 一.应用层 1.网络通信数据的实质 网络上传输的数据&#xff0c;本质就是字符串&#xff08;准确的说&#xff0c;是二进制的字符串&#xff09; Java中的各种对象&#xff0c;是无法直接传输的 &…

基于STM32两轮自平衡小车系统设计与控制

**单片机设计介绍&#xff0c;1650【毕设课设】基于STM32两轮自平衡小车系统设计与控制 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序文档 六、 文章目录 一 概要 主控芯片用的是100脚的STM32F103VET6&#xff0c;陀螺仪用的是MPU6050&#xff0c;电机…

中微爱芯74逻辑兼容替代TI/ON/NXP工规品质型号全

这里写自定义目录标题 工业级型号全产品线概述![在这里插入图片描述](https://img-blog.csdnimg.cn/097ef810b2234f07b0c0c1e962a73761.png)批量应用行业头部客户兼容替代封装对照逻辑参数对比电平转换系列型号对照HC/HCT 系列型号对照AHC/AHCT 系列型号对照LV/LVC 系列型号对照…

计算机视觉-光源的目的和作用

光源的目的 机器视觉系统的核心是图像采集和图像处理&#xff0c;而光源则是影响图像水平的重要因素&#xff0c;通过适当的光源照明&#xff0c;使图像中的目标信息与背景信息得到更好的分离&#xff0c;可大大降低图像识别难度&#xff0c;提高系统的精度和可靠性。 对于机器…