当前位置: 首页 > news >正文

【C++从入门到放弃】类和对象(中)———类的六大默认成员函数

🧑‍💻作者: @情话0.0
📝专栏:《C++从入门到放弃》
👦个人简介:一名双非编程菜鸟,在这里分享自己的编程学习笔记,欢迎大家的指正与点赞,谢谢!

在这里插入图片描述

类和对象(中)

  • 前言
  • 一、构造函数
    • 1. 构造函数的概念
    • 2. 构造函数的特性
  • 二、析构函数
    • 1. 析构函数的概念
    • 2. 析构函数的特征
  • 三、 拷贝构造函数
    • 1. 拷贝构造函数的概念
    • 2. 拷贝构造函数的特征
  • 四、 赋值运算符重载
    • 1.运算符重载
    • 2. 赋值运算符重载
  • 四、const成员函数
  • 五、取地址及const取地址操作符重载
  • 总结


前言

  在上一篇文章中提到过空类的存在,它的大小为一个字节,目的就是为了标识这个类的存在。但是空类中真的什么都没有吗?当然不是的,任何类在什么都不写时,编译器会自动生成以下六个默认成员函数。而这六个默认成员函数只会在用户没有显式定义的情况下被编译器自动生成,如若用户自己显示定义了这几个函数,那么编译器不会自动生成默认的成员函数。编译器自动生成的函数称为默认成员函数。

在这里插入图片描述


一、构造函数

1. 构造函数的概念

class Date
{
public:void Init(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 d;d.Init(2000, 1, 9);d.Print();return 0;
}

  在创建了一个类对象,可以通过公有方法 Init 给对象设置日期,但如果每次创建对象时都调用该方法设置信息,那是不是有点麻烦,那能否在对象创建时,就将信息设置进去呢?

  构造函数是一个特殊的成员函数,名字与类名相同,创建类类型对象时由编译器自动调用,保证每个数据成员都有 一个合适的初始值,并且在对象的生命周期内只调用一次。

2. 构造函数的特性

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

其特征如下:

  1. 函数名与类名相同。
  2. 无返回值。
  3. 对象实例化时编译器自动调用对应的构造函数。
  4. 构造函数可以重载。
class Date
{
public :// 1.无参构造函数Date (){}// 2.带参构造函数Date (int year, int month, int day){_year = year ;_month = month ;_day = day ;}
private :int _year ;int _month ;int _day ;
};
int main()
{Date d1; // 调用无参构造函数Date d2 (2000, 1, 9); // 调用带参的构造函数
}
  1. 如果类中没有显式定义构造函数,则C++编译器会自动生成一个无参的默认构造函数,一旦用户显式定义编译器将不再生成。
class 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类中构造函数放开,代码编译失败,因为一旦显式定义任何构造函数,编译器将不再生成// d1对象并没有初始值,所以应该去调用无参构造函数或者全缺省构造函数,而显示定义的构造函数并非默认构造函数Date d1;return 0;
}
  1. 无参的构造函数全缺省的构造函数都称为默认构造函数,并且默认构造函数只能有一个
    注意:无参构造函数、全缺省构造函数、编译器默认生成的构造函数,都是默认成员函数。
class Date
{ 
public:Date()//无参的构造函数{_year = 1900 ;_month = 1 ;_day = 1;}Date (int year = 2000, int month = 1, int day = 9)//全缺省构造函数{_year = year;_month = month;_day = day;}
private :int _year ;int _month ;int _day ;
};

上面的代码会有问题,因为同时出现了两个默认构造函数,当定义了一个无初始值的对象时,编译器就不知道该去调用哪个构造函数。

  1. 关于编译器生成的默认成员函数,我们会发现,不实现构造函数的情况下,编译器会生成默认的构造函数。但是看起来默认构造函数又好像没什么用?一个对象调用了编译器生成的默认构造函数,但是这个对象的年月日依旧是随机值。也就说在这里编译器生成的默认构造函数并没有什么用?其实这也算是C++的小缺点吧,可能祖师爷在这个点上并没有想那么多。

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

class 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;return 0;
}

注意:C++11 中针对内置类型成员不初始化的缺陷,又打了补丁,即:内置类型成员变量在类中声明时可以给默认值。 当你在定义对象时给了初始值,那么就会使用你所给的初始值,若没给初始值,那么就会使用这个在声明时给到的默认值,避免随机值的出现。

class Date
{
private:// 基本类型(内置类型)
int _year = 2000;
int _month = 1;
int _day = 9;// 自定义类型
Time _t;
};

二、析构函数

1. 析构函数的概念

  通过对构造函数的学习,明白了一个对象是怎样来的,那么一个对象又是怎么没的呢?
  析构函数与构造函数功能相反,析构函数不是完成对象的销毁,局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成类对象的资源清理工作。

2. 析构函数的特征

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

  1. 析构函数名是在类名前加上字符 ~。
  2. 无参数无返回值。
  3. 一个类有且只有一个析构函数。若未显式定义,系统会自动生成默认的析构函数。
  4. 对象生命周期结束时,C++编译系统系统自动调用析构函数。
  5. 编译器生成的默认析构函数,对会自定类型成员调用它的析构函数。
class Time
{
public:~Time(){cout << "~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 d;return 0;
}

程序运行结束后输出:~Time()

  在main方法中根本没有直接创建Time类的对象,为什么最后会调用Time类的析构函数?

  解释: 在main函数中,创建了Date类,其中包含四个成员变量,其中一个为自定义类型变量,在创建了Date类对象时不仅通过Date类的构造函数对内置类型的三个变量初始化,还要去调用自定义类型变量对应的构造函数完成初始化,那么程序退出时首先要完成对Date类对象的析构,除此之外,还要对Time类完成析构函数,因为在Date类中为完成 _t 的初始化而调用了Time类的构造函数。
  创建哪个类的对象则调用该类的析构函数,销毁那个类的对象则调用该类的析构函数。

三、 拷贝构造函数

1. 拷贝构造函数的概念

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

2. 拷贝构造函数的特征

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

1. 拷贝构造函数是构造函数的一个重载形式。
2. 拷贝构造函数的参数只有一个且必须使用引用传参,使用传值方式会引发无穷递归调用。

class Date
{
public:Date(int year = 2000, int month = 1, int day = 9){_year = year;_month = month;_day = day;}// Date(const Date d)  错误写法,会引起无穷递归调用Date(const Date& d){ _year = d._year;_month = d._month;_day = d._day;}
private:int _year;int _month;int _day;
};
int main()
{Date d1;Date d2(d1);return 0; 
}

   至于为什么不能使用传值的方式调用拷贝构造函数,原因在于:通过 d1对象去拷贝构造一个新对象 d2 ,而采用传值的方式会对 d1 重新创建一个临时对象 d ,这个创建临时对象的过程又被认为是一个拷贝构造的过程,那么就又会去调用拷贝构造函数,以此类推就会出现拷贝构造函数的无穷递归,而采用传引用的方式就不会出现创建临时对象这个过程。
在这里插入图片描述

3. 若未显示定义,系统生成默认的拷贝构造函数。 默认的拷贝构造函数对象按内存存储按字节序完成拷贝,这种拷贝我们叫做浅拷贝,或者值拷贝。

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;   // 用已经存在的d1拷贝构造d2,此处会调用Date类的拷贝构造函数// 但Date类并没有显式定义拷贝构造函数,则编译器会给Date类生成一个默认的拷贝构造函数Date d2(d1);return 0;
}

注意:在编译器生成的默认拷贝构造函数中,内置类型是按照字节方式直接拷贝的,而自定义类型是调用其拷贝构造函数完成拷贝的。

4. 编译器生成的默认拷贝构造函数已经可以完成字节序的值拷贝了,还需要自己显式实现吗?当然像日期类这样的类是没必要的。那么下面的类呢?验证一下试试?

// 这里会发现下面的程序会崩溃掉,原因就在于析构函数
typedef int DataType;
class Stack
{
public:Stack(size_t capacity = 10){_array = (DataType*)malloc(capacity * sizeof(DataType));if (nullptr == _array){perror("malloc申请空间失败");return;}_size = 0;_capacity = capacity;}void Push(const DataType& data){// CheckCapacity();_array[_size] = data;_size++;}~Stack(){if (_array){free(_array);_array = nullptr;_capacity = 0;_size = 0;}}private:DataType *_array;size_t _size;size_t _capacity;
};int main()
{Stack s1;s1.Push(1);s1.Push(2);s1.Push(3);s1.Push(4);Stack s2(s1);return 0;
}

  通过调试发现,对象 s1 和对象 s2 的其中一个参数(array)的地址是一样的,这也就问题所在。

  通过构造函数创建了一个类对象 s1 ,并为其开辟了十字节的空间,然后再为其中存入了4个元素;
  s2 对象使用 s1 拷贝构造,而 Stack 类中没有显式定义拷贝构造函数,则编译器会给 Stack 类生成一个默认的拷贝构造函数,默认的拷贝构造函数是按值拷贝的,即将对象 s1 中的所有内容拷贝给 s2 (s1类对象中第一成员变量是一个地址,相当于把地址复制给了 s2)那么 s1 和 s2 中的 第一个成员变量指向了同一块空间;
  当程序退出时,s1 和 s2 都要销毁,s2 先销毁,通过析构函数将 _array 数组那块空间释放掉,但是对象 s1 并不知道这块空间已经释放,当它再次通过析构函数释放空间时就出现程序崩溃。

注意:类中如果没有涉及资源(堆内存空间、文件指针等)管理时,拷贝构造函数是否写都可以;一旦涉及到资源申请时,则拷贝构造函数是一定要写的,否则就是浅拷贝。

5. 拷贝构造函数的典型应用场景

使用已存在对象创建新对象
函数参数类型为类类型对象
函数返回值类型为类类型对象

class Date
{
public:Date(int year, int month, 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 tmp(d);return tmp;
}int main()
{Date d1(2000,1,9);Test(d1);return 0;
}

在这里插入图片描述

为了提高程序效率,一般在对象传参时尽量使用引用类型,返回可根据实际场景选择是否也可以选择引用返回。

四、 赋值运算符重载

1.运算符重载

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

  函数名字为:关键字operator后面接需要重载的运算符符号。

  函数原型:返回值类型 + operator + 操作符 + (参数列表)

注意:

★ 不能通过连接其他符号来创建新的操作符:比如operator@
★ 重载操作符必须有一个类类型
★ 用于内置类型的操作符,其含义不能改变,例如:内置的整型+,不 能改变其含义
★ 作为类成员的重载函数时,其形参看起来比操作数数目少1,因为成员函数中有一个默认的形参this,限定为第一个形参
★ .* 、:: 、sizeof 、?: 、. 注意以上5个运算符不能重载。

class Date
{ 
public:Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month; _day = day;}// bool operator==(Date* this, const Date& d2)// 这里需要注意的是,左操作数是this指向的调用函数的对象bool operator==(const Date& d2){return _year == d2._year;&& _month == d2._month&& _day == d2._day;}
private:int _year;int _month;int _day;
};
int main ()
{Date d1(2023, 1, 9);Date d2(2000, 1, 9);cout<<(d1 == d2)<<endl; return 0;
}

2. 赋值运算符重载

1. 赋值运算符重载格式:

参数类型:const T&,传递引用可以提高传参效率
返回值类型:T&,返回引用可以提高返回的效率,有返回值目的是为了支持连续赋值
检测是否自己给自己赋值
返回*this :要复合连续赋值的含义

class Date
{ 
public :Date(int year = 2000, int month = 1, int day = 9){_year = year;_month = month;_day = day;} Date (const Date& d){_year = d._year;_month = d._month;_day = d._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 ;
};

2. 赋值运算符只能重载成类的成员函数不能重载成全局函数

class Date
{
public:Date(int year = 1900, int month = 1, int day = 1){ _year = year;_month = month;_day = day;}int _year;int _month;int _day;
};// 赋值运算符重载成全局函数,注意重载成全局函数时没有this指针了,需要给两个参数
Date& operator=(Date& left, const Date& right)
{if (&left != &right){left._year = right._year;left._month = right._month;left._day = right._day;}return left;
}// 编译失败:
// error C2801: “operator =”必须是非静态成员

原因: 赋值运算符如果不显式实现,编译器会生成一个默认的。此时用户再在类外自己实现一个全局的赋值运算符重载,就和编译器在类中生成的默认赋值运算符重载冲突了,故赋值运算符重载只能是类的成员函数。

3. 用户没有显式实现时,编译器会生成一个默认赋值运算符重载,以值的方式逐字节拷贝(浅拷贝)。注意:内置类型成员变量是直接赋值的,而自定义类型成员变量需要调用对应类的赋值运算符重载完成赋值。

class Time
{
public:Time(){_hour = 1;_minute = 1;_second = 1;}Time& operator=(const Time& t){if (this != &t){_hour = t._hour;_minute = t._minute;_second = t._second;}return *this;}private:int _hour;int _minute;int _second;
};class Date
{
private:// 基本类型(内置类型)int _year = 2000;int _month = 1;int _day = 1;// 自定义类型Time _t;
};int main()
{Date d1;Date d2;d1 = d2;return 0;
}

  既然编译器生成的默认赋值运算符重载函数已经可以完成字节序的值拷贝了,还需要自己实现吗?如果类中未涉及到资源管理,赋值运算符是否实现都可以;一旦涉及到资源管理则必须要实现。这就和拷贝构造是一个道理。

四、const成员函数

  将const修饰的“成员函数”称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。

在这里插入图片描述

class Date
{
public:Date(int year, int month, int day){_year = year;_month = month;_day = day;}void Display(){cout << "Display()" << endl;cout << "year:" << _year << endl;cout << "month:" << _month << endl;cout << "day:" << _day << endl << endl;}void Display() const{cout << "Display()const" << endl;cout << "year:" << _year << endl;cout << "month:" << _month << endl;cout << "day:" << _day << endl << endl;}
private:int _year; // 年int _month; // 月int _day; // 日};int main()
{Date d1(2023, 3, 1);d1.Display();const Date d2(2023, 3, 1);d2.Display();return 0;
}

在这里插入图片描述
注意:const 修饰成员函数有两种:

  1. 当const 处在成员函数的最前面时,它代表的意思是该函数的返回值不可被修改;
  2. 当const 处在成员函数的最末尾时,它代表的意思是该函数的成员变量不可被修改。

五、取地址及const取地址操作符重载

class Date
{ 
public :Date* operator&(){return this ;}const Date* operator&()const{return this ;}
private :int _year ; int _month ; int _day ; 
};

  这两个运算符一般不需要重载,使用编译器生成的默认取地址的重载即可,只有在特殊的情况下,才需要重载,比如你想让获取到指定的内容!


总结

以上就是对类的六大默认成员函数的简单介绍,掌握了这些知识,对后面的C++学习会有很大的步骤,我也相信自己会一步一步往前走,更上一层楼!

相关文章:

【C++从入门到放弃】类和对象(中)———类的六大默认成员函数

&#x1f9d1;‍&#x1f4bb;作者&#xff1a; 情话0.0 &#x1f4dd;专栏&#xff1a;《C从入门到放弃》 &#x1f466;个人简介&#xff1a;一名双非编程菜鸟&#xff0c;在这里分享自己的编程学习笔记&#xff0c;欢迎大家的指正与点赞&#xff0c;谢谢&#xff01; 类和对…...

白盒测试重点复习内容

白盒测试白盒测试之逻辑覆盖法逻辑覆盖用例设计方法1.语句覆盖2.判定覆盖(分支覆盖)3.条件覆盖4.判定条件覆盖5.条件组合覆盖6.路径覆盖白盒测试之基本路径测试法基本路径测试方法的步骤1.根据程序流程图画控制流图2.计算圈复杂度3.导出测试用例4.准备测试用例5.例题白盒测试总…...

【13】linux命令每日分享——groupadd建立组

大家好&#xff0c;这里是sdust-vrlab&#xff0c;Linux是一种免费使用和自由传播的类UNIX操作系统&#xff0c;Linux的基本思想有两点&#xff1a;一切都是文件&#xff1b;每个文件都有确定的用途&#xff1b;linux涉及到IT行业的方方面面&#xff0c;在我们日常的学习中&…...

《第一行代码》 第十章:服务

一&#xff0c;在子线程中更新UI 1&#xff0c;新建项目&#xff0c;修改布局代码 <RelativeLayout xmlns:android"http://schemas.android.com/apk/res/android"android:layout_width"match_parent"android:layout_height"match_parent"&g…...

简单介绍编程进制

十进制 十进制的位权为 10&#xff0c;比如十进制的 123&#xff0c;123 1 * 10 ^ 2 2 * 10 ^ 1 3 * 10 ^ 0。 二进制 二进制的位权为 2&#xff0c;比如十进制的 4&#xff0c;二进制为 100&#xff0c;4 1 * 2 ^ 2 0 * 2 ^ 1 0 *2 ^ 0。 Java7 之前&#xff0c;不支…...

windows忘记开机密码怎么办

windows忘记开机密码怎么办 清除windows登录密码 清除windows登录密码简单方法 开机到欢迎界面时&#xff0c;按CtrlAltDelete两次&#xff0c;跳出帐号窗口&#xff0c;输入用户名&#xff1a;administrator&#xff0c;回车&#xff0c; 或者启动时按F8 选“带命令行的安全…...

SpringCloud:Eureka

目录 一、eureka的作用 二、搭建Eureka服务端 三、添加客户端 四、服务发现 提供者与消费者 服务提供者&#xff1a;一次业务中&#xff0c;被其它微服务调用的服务。&#xff08;提供接口给其它微服务) 服务消费者&#xff1a;一次业务中&#xff0c;调用其它微服务的服…...

如何获取或设置CANoe以太网网卡信息(SET篇)

CAPL提供了一系列函数用来操作CANoe网卡。但是,但是,首先需要明确一点,不管是获取网卡信息,还是设置网卡信息,只能访问CAPL程序所在的节点下的网卡,而不是节点所在的以太网通道下的所有网卡 关于第一张图中,Class节点下,有三个网卡:Ethernet1、VLAN 1.100、VLAN 1.200…...

【软件测试面试题】项目经验?资深测试 (分析+回答) 我不信你还拿不到offer......

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 在面试过程中&#…...

tensorflow lite简介-移动设备端机器学习

TensorFlow Lite 是一组工具&#xff0c;可帮助开发者在移动设备、嵌入式设备和 loT 设备上运行模型&#xff0c;以便实现设备端机器学习。 支持多平台 支持多种平台&#xff0c;涵盖 Android 和 iOS 设备、嵌入式 Linux 和微控制器。 原理/流程 工作原理或者使用流程就是上面…...

Node.js常用知识

1、什么是 Node.js 【】Node.js 是一个基于 Chrome V8 引擎的 JavaScript 运行环境。浏览器是 js 的前端运行环境&#xff0c;node.js 是 js 的后端运行环境。他们都有 V8 引擎&#xff0c;有各自的内置 API 2、fs 文件系统模块 【】fs 模块是 Node.js 官方提供的、用来操作文件…...

踩坑:maven打包失败的解决方式总结

Maven打包失败原因总结如下&#xff1a; 失败原因1&#xff1a;无法使用spring-boot-maven-plugin插件 使用spring-boot-maven-plugin插件可以创建一个可执行的JAR应用程序&#xff0c;前提是应用程序的parent为spring-boot-starter-parent。 需要添加parent的包spring-boot…...

【C++】位图

文章目录位图概念位图操作位图代码位图应用位图概念 boss直接登场&#xff1a; 给40亿个不重复的无符号整数&#xff0c;没排过序。给一个无符号整数&#xff0c;如何快速判断一个数是否在这40亿个数中❓ 40亿个整数&#xff0c;大概就是16GB。40亿个字节大概就是4GB。 1Byt…...

蓝桥杯-考勤刷卡

蓝桥杯-考勤刷卡1、问题描述2、解题思路3、代码实现1、问题描述 小蓝负责一个公司的考勤系统, 他每天都需要根据员工刷卡的情况来确定 每个员工是否到岗。 当员工刷卡时, 会在后台留下一条记录, 包括刷卡的时间和员工编号, 只 要在一天中员工刷过一次卡, 就认为他到岗了。 现在…...

如何利用站内推广和站外推广提高转化率?

在如今的网络时代&#xff0c;拥有一个好的网站是非常重要的。但是&#xff0c;光有一个好的网站是不够的&#xff0c;为了达到我们的目标&#xff0c;需要不断地提高网站的转化率。而在实现这个目标的过程中&#xff0c;站内推广和站外推广是两个非常关键的因素。 站内推广是…...

Java多线程(三)——线程池及定时器

线程池就是一个可以复用线程的技术。前面三种多线程方法就是在用户发起一个线程请求就创建一个新线程来处理&#xff0c;下次新任务来了又要创建新线程&#xff0c;而创建新线程的开销是很大的&#xff0c;这样会严重影响系统的性能。线程池就相当于预先创建好几个线程&#xf…...

Linux命令行安装Oracle19c教程和踩坑经验

安装 下载 从 Oracle官方下载地址 需要的版本&#xff0c;本次安装是在Linux上使用yum安装&#xff0c;因此下载的是RPM。另外&#xff0c;需要说明的是&#xff0c;Oracle加了锁的下载需要登录用户才能安装&#xff0c;而用户是可以免费注册的&#xff0c;这里不做过多说明。 …...

Linux常用命令等

目录 1.Linux常用命令 (1)系统命令 (2)文件操作命令 2.vim编辑器 3.linux系统中,软件安装 (1) rpm 安装,RedHat Package Manager (2)yum 安装 (3)源代码编译安装 1.Linux常用命令 Linux命令是非常多的,对于像嵌入式开发工程师,运维工程师需要掌握的命令是非常多的.对于…...

CEC2014:鱼鹰优化算法(Osprey optimization algorithm,OOA)求解CEC2014(提供MATLAB代码

一、鱼鹰优化算法简介 鱼鹰优化算法&#xff08;Osprey optimization algorithm&#xff0c;OOA&#xff09;由Mohammad Dehghani 和 Pavel Trojovsk于2023年提出&#xff0c;其模拟鱼鹰的捕食行为。 鱼鹰是鹰形目、鹗科、鹗属的仅有的一种中型猛禽。雌雄相似。体长51-64厘米…...

MyBatis底层原理【源码运行时序图】

MyBatis初始化流程&#x1f6f7; 以下代码为例&#x1f389; &#x1f387;可对应源码阅读 MyBatis初始化流程✨ #mermaid-svg-yoG1e8Dnp3UIAOUW {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-yoG1e8Dnp3UIAOU…...

k8s 系列之 CoreDNS 解读

k8s 系列之 CoreDNS CoreDNS工作原理 kuberntes 中的 pod 基于 service 域名解析后&#xff0c;再负载均衡分发到 service 后端的各个 pod 服务中&#xff0c;如果没有 DNS 解析&#xff0c;则无法查到各个服务对应的 service 服务 在 Kubernetes 中&#xff0c;服务发现有几…...

从测试鸡蛋硬度到跳表的设计

我回忆起六七年前的一道题鸡蛋掉落问题&#xff0c;有幸在leetCode上找到题目了 原题是2枚鸡蛋 leetCode有拓展&#xff0c;k枚鸡蛋 具体的思路是这样的。 以2枚鸡蛋验证100层为例 不能直接二分查找&#xff0c;因为你在50层测试时&#xff0c;如果直接鸡蛋碎了&#xff0c;那…...

3D立体视觉成像原理介绍【一 】

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录前言什么是基线&#xff1f;基线是如何影响3D图像质量激光三角测量飞行时间结构光相机时间编码结构光前言 本文将介绍3D立体视觉的成像原理&#xff0c;包括【激光三…...

CEC2021:鱼鹰优化算法(Osprey optimization algorithm,OOA)求解CEC2021(提供MATLAB代码

一、鱼鹰优化算法简介 鱼鹰优化算法&#xff08;Osprey optimization algorithm&#xff0c;OOA&#xff09;由Mohammad Dehghani 和 Pavel Trojovsk于2023年提出&#xff0c;其模拟鱼鹰的捕食行为。 鱼鹰是鹰形目、鹗科、鹗属的仅有的一种中型猛禽。雌雄相似。体长51-64厘米…...

0301_对应的南京比特物联网

0301_对应的南京比特物联网目录概述需求&#xff1a;设计思路实现思路分析1.流程拓展实现性能参数测试&#xff1a;参考资料和推荐阅读Survive by day and develop by night. talk for import biz , show your perfect code,full busy&#xff0c;skip hardness,make a better …...

钡铼技术BL302 ARM工控机QT图形化界面开发的实践

QT是一种跨平台的应用程序框架&#xff0c;用于开发图形用户界面(GUI)、网络应用程序和嵌入式应用程序。QT提供了丰富的GUI组件和工具&#xff0c;使开发人员能够轻松地创建专业级别的应用程序。QT使用C编写&#xff0c;支持多种操作系统&#xff0c;包括Windows、Linux、macOS…...

Python try except异常处理详解(入门必读)

Python 中&#xff0c;用try except语句块捕获并处理异常&#xff0c;其基本语法结构如下所示&#xff1a; try:可能产生异常的代码块 except [ (Error1, Error2, ... ) [as e] ]:处理异常的代码块1 except [ (Error3, Error4, ... ) [as e] ]:处理异常的代码块2 except [Exc…...

信息系统基本知识(三)软件工程

1.4 软件工程 定义&#xff1a;将系统的、规范的、可度量的工程化方法应用于软件开发、运行和维护的全过程即上述方法的研究 软件工程由方法、工具和过程三个部分组成 1.4.1 需求分析 软件需求是指用户对新系统在功能、行为、性能、设计约束等方面的期望。 需求层次 业务…...

Linux下软件部署安装管理----rpmbuild打包rpm包部署安装

来源&#xff1a;微信公众号「编程学习基地」 文章目录1.安装rpmbuild2.rpm包制作打包rpm包3.rpm包安装4.rpm包卸载1.安装rpmbuild yum install rpmbuild yum install rpmdevtools创建rpm包管理路径&#xff0c;生成rpm相关目录 RPM打包的时候需要编译源码&#xff0c;还需要…...

ThreadLocal学会了这些,你也能和面试官扯皮了!

前言 我们都知道,在多线程环境下访问同一个共享变量,可能会出现线程安全的问题,为了保证线程安全,我们往往会在访问这个共享 变量的时候加锁,以达到同步的效果,如下图所示。 对共享变量加锁虽然能够保证线程的安全,但是却增加了开发人员对锁的使用技能,如果锁使用不当…...

好的网站建设公司哪家好/360网站推广客服电话

达尔文的进化论是科学史上最大的谎言&#xff0c;在这个谎言的影响下&#xff0c;人类归根于动物&#xff0c;抛弃了道德的约束&#xff0c;失控地发展着私欲&#xff0c;造就了误入歧途的历史。下面转贴一文&#xff0c;剥去历史上最伪的伪科学的画皮&#xff0c;讨伐达尔文的…...

招聘网站比对表怎么做/网站排名seo培训

本文转自&#xff1a;http://www.cnblogs.com/henw/archive/2011/09/23/2186387.html 1. 需要引用的类库 ?1234using System.Net; using System.IO; using System.Text; using System.Text.RegularExpressions;2. 获取其他网站网页内容的关键代码 ?12345WebRequest request …...

广州市网站建设品牌/网站seo服务公司

用过jQuery的朋友一定对jQuery中方法的链式调用印象深刻&#xff0c;貌似现在很多库都支持了方法的链式调用,比如YUI3等。链式调用是一个非常不错的语法特性&#xff0c;能让代码更加简洁、易读。很多时候链式调用可以避免多次重复使用一个对象变量。今天有人在群里说起javascr…...

大连做网站的网络公司/seo哪个软件好

一、安装Java SE JKD A、下载 http://www.oracle.com/technetwork/java/javase/downloads/index.html?ssSourceSiteIdocomen 选择最新版本&#xff0c;当前最新版本 1.8.0 。下载 jdk-8u45-linux-x64.tar.gz 。 B、解压下载包&#xff0c;添加环境变量。 $ sudo vim ~/.bash…...

做网站源代码/百度指数网址

通过kmeans分析出租车数据并进行可视化&#xff08;1&#xff09;数据准备&#xff08;2&#xff09;创建dataframe&#xff08;3&#xff09;kmeans聚类分析&#xff08;4&#xff09;调用百度API进行数据可视化&#xff08;1&#xff09;数据准备 采用数据为出租车载客时的G…...

idc 网站备案/制作网站软件

#参考资料大型分布式网站架构设计与实践 #感悟&#xff1a;书读百遍&#xff0c;其意自见 #QQ群北京it—推荐–交流&#xff1a;300458205 #群专注内推、大数据、云计算、Java、Android、UI等技术交流&#xff0c;欢迎你的加入。 看的越多&#xff0c;发现会的越少&#xff…...