【C++实战项目】Date日期类 --- 运算符重载的深入探索

在这里插入图片描述

📷 江池俊:个人主页
🔥 个人专栏:✅C++那些事儿 ✅Linux技术宝典
🌅 此去关山万里,定不负云起之望


在这里插入图片描述

文章目录

    • 引言
    • 一、为什么需要运算符重载?
    • 二、日期类的实现
      • 1. 基本框架
      • 2. 预备工作
      • 3. Date 类中六大默认成员函数的使用
        • 3.1 全缺省的构造函数
        • 3.2 拷贝构造函数
        • 3.3 析构函数
        • 3.4 赋值运算符重载
        • 3.5 const 成员函数
        • 3.6 取地址操作符重载和const取地址操作符重载
      • 4. 运算符重载
        • 4.1 += 和 + 运算符重载
        • 4.2 -= 和 - 运算符重载
        • 4.3 前置++ 和 后置++ 运算符重载
        • 4.4 前置-- 和 后置-- 运算符重载
        • 4.5 > 和 == 运算符重载
        • 4.6 >= 、< 、<= 和 != 运算符重载
        • 4.7 日期-日期
        • 4.8 流插入 << 和 流提取 >> 运算符重载
    • 5. 日期类源码
      • 5.1 Date.h文件
      • 5.2 Date.cpp 文件
    • 总结


引言

在C++编程中,运算符重载是一种强大的功能,它允许我们为自定义的数据类型定义运算符的行为。这种特性在创建像日期(Date)这样的类时尤其有用,因为它允许我们更自然、更直观地操作这些类的实例。通过日期类我们还能够实现一个简单的日期时间计数器的功能,想必大家都很期待接下来的内容。

在这里插入图片描述

在本篇博客中,我们将深入探索如何为Date类重载运算符,并了解其中的一些最佳实践和潜在陷阱。

Date.h文件下放日期类的声明代码,Date.c文件下放日期类的实现代码


一、为什么需要运算符重载?

运算符重载可以让我们使用更直观、更自然的方式来操作日期。

在创建日期类时,我们可能希望执行如下操作:

  • 对两个日期进行加法运算以得到一个新的日期(例如,将5天加到今天的日期上)。
  • 比较两个日期以确定哪个日期更早或更晚。
  • 从一个日期中减去另一个日期以得到它们之间的时间差。
  • 等等…

为了实现这些操作,我们需要为Date类重载相应的运算符,如+、-、<等。


二、日期类的实现

1. 基本框架

class Date
{
public:// 获取某年某月的天数int GetMonthDay(int year, int month) const;// 检查日期是否合法bool CheckInvalid();// 全缺省的构造函数Date(int year = 1900, int month = 1, int day = 1);// 拷贝构造函数// d2(d1)Date(const Date& d);// 赋值运算符重载// d2 = d3 -> d2.operator=(&d2, d3)Date& operator=(const Date& d);// 析构函数~Date();// ======== 有关日期计算的运算符重载 ========// 日期+=天数Date& operator+=(int day);// 日期+天数Date operator+(int day);// 日期-天数Date operator-(int day);// 日期-=天数Date& operator-=(int day);// 前置++Date& operator++();// 后置++Date operator++(int);// 后置--Date operator--(int);// 前置--Date& operator--();// =========== 比较运算符的重载 ==========// >运算符重载bool operator>(const Date& d) const;// ==运算符重载bool operator==(const Date& d) const;// >=运算符重载bool operator >= (const Date& d) const;// <运算符重载bool operator < (const Date& d) const;// <=运算符重载bool operator <= (const Date& d) const;// !=运算符重载bool operator != (const Date& d) const;// 日期-日期 返回天数int operator-(const Date& d);// 打印,const成员函数修饰的是成员函数隐含的this指针,表明不能修改任何成员变量void Print() const{cout << _year << "-" << _month << "-" << _day << endl;}// 友元声明,可以在类的任何位置friend ostream& operator<<(ostream& out, const Date& d);friend istream& operator>>(istream& in, Date& d);
private:int _year;int _month;int _day;
};// 类外声明
ostream& operator<<(ostream& out, const Date& d);
istream& operator>>(istream& in, Date& d);

2. 预备工作

在构造日期类时我们很有可能不小心传入错误的日期时间,比如 2023-02-29 或 2024-4-31这样的时间,所以为了确保日期的正确性,在构造函数中我们需要检查日期的合法性,因此在写构造函数前需要先实现两个成员函数:

  1. CheckInvalid() 函数:功能是检查日期是否合法
  2. GetMonthDay(int year, int month) 函数:功能是获取某年某月的天数
// 获取某年某月的天数
int Date::GetMonthDay(int year, int month) const
{static int days[13] = { 0,31,28,31,30,31,30,31,30,31,31,30,31 };if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))){return 29;}return days[month];
}// 检查日期是否合法
bool Date::CheckInvalid()
{if (_year <= 0|| _month < 1 || _month > 12|| _day < 1 || _day > GetMonthDay(_year, _month)){return false;}return true;
}

注意:这里 days 数组被声明为静态数组,静态数组在程序的生命周期内只会被初始化一次。由于 GetMonthDay 函数被频繁调用,将其声明为静态可以确保它只在程序开始时分配一次内存,而不是每次调用函数时都重新分配。这可以提高空间效率

3. Date 类中六大默认成员函数的使用

3.1 全缺省的构造函数
// 全缺省的构造函数
Date(int year = 1900, int month = 1, int day = 1)
{_year = year;_month = month;_day = day;if (!CheckInvalid()){cout << *this << "构造日期非法" << endl;exit(-1);}
}

通过构造函数即可对实例化对象进行初始化。

3.2 拷贝构造函数

拷贝构造:同类型的一个已经存在的对象去初始化一个新的要创建的对象

// 拷贝构造函数
// d2(d1)
Date(const Date& d)
{_year = d._year;_month = d._month;_day = d._day;
}
3.3 析构函数
// 析构函数
~Date()
{//cout << "~Date()" << endl;
}

日期类并 没有申请资源(动态开辟内存,打开文件等),所以这里的析构函数可写可不写,系统默认生成的就够用。

3.4 赋值运算符重载

赋值重载:已经存在的两个对象,一个拷贝赋值给另一个

// 赋值运算符重载
// d2 = d3 -> d2.operator=(&d2, d3)
Date& operator=(const Date& d)
{if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;
}
3.5 const 成员函数
// 举例:
// 打印,const成员函数修饰的是成员函数隐含的this指针,表明不能修改任何成员变量
void Print() const
{cout << _year << "-" << _month << "-" << _day << endl;
}

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

如果我们只需要访问成员变量而非修改成员变量,那么此时我们就可以使用 const成员函数 来提高代码的健壮性。

3.6 取地址操作符重载和const取地址操作符重载
// 取地址操作符重载
Date* operator&()
{return this;//return nullptr;
}// const取地址操作符重载
const Date* operator&()const
{return this;//return nullptr;
}

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

这里以注释的两个return语句为例,可以返回空指针给别人,让对方找不到指定的类对象。(所以大多数情况下我们都不需要重载这两个成员函数,使用编译器默认生成的即可


4. 运算符重载

此处详细讲解 += 和 + 运算符的重载,-= 和 - 运算符的重载与其类似。

因此,对于前置++和后置++,前置- -和后置- -运算符重载,详细讲解前者

4.1 += 和 + 运算符重载

:实现了 += 运算符的重载后,对于 + 运算符的重载就可以利用 += 运算符来实现。

// 日期+=天数
Date& Date::operator+=(int day)
{_day += day;while (_day > GetMonthDay(_year, _month)){_day -= GetMonthDay(_year, _month);if (_month == 12){_month = 1;_year++;}else{_month++;}}return *this;
}
// 日期+天数
Date Date::operator+(int day)
{Date temp = *this; // 调用拷贝构造,因为temp不是一个已存在的对象temp += day;return temp;
}
  • operator+= 的算法思想和步骤:

    1. 输入Date对象的一个引用和一个整数(代表天数)。
    2. 算法思想:将给定的天数加到当前日期的天数上,并相应地调整月份和年份,以确保日期仍然有效。
    3. 步骤
      • 将当前日期的天数(_day)与给定的天数相加。
      • 检查更新后的天数是否超过了当前月份的天数(通过调用GetMonthDay函数)。
      • 如果超过了,从当前月份的天数中减去超出的部分,并更新月份和年份。
        • 如果月份是12月,将月份设置为1月,年份加1。
        • 否则,将月份加1。
      • 返回Date对象的引用,以便进行链式操作。
  • operator+ 的算法思想和步骤:

    1. 输入Date对象的一个实例和一个整数(代表天数)。
    2. 算法思想:创建一个Date对象的副本,并将给定的天数加到副本上,然后返回调整后的日期副本。
    3. 步骤
      • 创建一个Date类型的临时对象temp,并通过拷贝构造函数将其初始化为当前Date对象的副本。
      • 使用operator+=函数将给定的天数加到temp对象上。
      • 返回调整后的temp对象(值拷贝返回)。

:返回Date对象的引用(在operator+=中)允许进行链式操作,如 dateObj += 5 += 3

4.2 -= 和 - 运算符重载
// 日期-天数
Date Date::operator-(int day)
{Date temp = *this;temp -= day;return temp;
}
// 日期-=天数
Date& Date::operator-=(int day)
{while (day >= _day){day -= _day;if (_month == 1){_month = 12;_year--;_day = GetMonthDay(_year, _month);}else{_month--;_day = GetMonthDay(_year, _month);}}_day -= day;return *this;
}
4.3 前置++ 和 后置++ 运算符重载
  1. 前置++:返回+1之后的结果

    • 注意:this指向的对象函数结束后不会销毁,故以引用方式返回提高效率
  2. 后置++:前置++和后置++都是一元运算符,为了让前置++与后置++形成能正确的重载,C++规定:后置++重载时多增加一个 int 类型的参数,但调用函数时该参数不用传递,编译器自动传递

    • 注意:后置++是先使用后+1,因此需要返回+1之前的旧值,故需在实现时需要先将 this 保存一份,然后给 this + 1,而temp是临时对象,因此只能以值的方式返回,不能返回引用。
// 前置++
Date& Date::operator++()
{*this += 1;return *this;
}
// 后置++
Date Date::operator++(int)
{Date temp = *this;*this += 1;return temp;
}
4.4 前置-- 和 后置-- 运算符重载
// 后置--
Date Date::operator--(int)
{Date temp = *this;*this -= 1;return temp;
}
// 前置--
Date& Date::operator--()
{*this -= 1;return *this;
}
4.5 > 和 == 运算符重载

注意:对于比较运算的重载,只要先重载了 > 和 == 运算符,其他运算符的重载就可以利用这两者来实现。

// >运算符重载
bool Date::operator>(const Date& d) const
{if (_year > d._year)return true;else if (_year == d._year){if (_month > d._month)return true;else if (_month == d._month){if (_day > d._day)return true;}}return false;
}// ==运算符重载
bool Date::operator==(const Date& d) const
{return _year == d._year&& _month == d._month&& _day == d._day;
}
4.6 >= 、< 、<= 和 != 运算符重载
// >=运算符重载
bool Date::operator >= (const Date& d) const
{return *this > d || *this == d;
}
// <运算符重载
bool Date::operator < (const Date& d) const
{return !(*this >= d);
}
// <=运算符重载
bool Date::operator <= (const Date& d) const
{return !(*this > d);
}
// !=运算符重载
bool Date::operator != (const Date& d) const
{return !(*this == d);
}
4.7 日期-日期
// 日期-日期 返回天数
int Date::operator-(const Date& d)
{int flag = 1;Date maxDate = *this;Date minDate = d;if (*this < d){flag = -1;maxDate = d;minDate = *this;}int n = 0;while (maxDate != minDate){minDate++;n++;}return flag * n;
}
  • 思路

    1. 比较日期:首先比较当前对象(*this)和传入的日期对象d,确定哪个日期更大,哪个更小。
    2. 确定符号:根据日期的大小关系确定结果的符号。如果当前对象更大,则结果为正;如果传入的日期更大,则结果为负。
    3. 计算天数差从较小的日期开始,逐步增加一天,直到两个日期相等。每次增加一天,就增加计数器的值
    4. 返回结果:根据符号和天数差计算最终的结果,并返回。
  • 步骤

    1. 声明变量
      • flag:用于表示结果的符号,初始化为1(表示正数)。
      • maxDateminDate:用于存储两个日期中较大和较小的日期,初始时分别设置为当前对象(*this)和传入的日期d
    2. 比较日期并确定符号
      • 使用if语句比较*thisd
      • 如果*this小于d,则交换maxDateminDate的值,并将flag设置为-1。
    3. 初始化计数器
      • 声明n并初始化为0,用于计算天数差。
    4. 计算天数差
      • 使用while循环,每次循环将minDate增加一天(即调用minDate++),并增加计数器n的值。
      • 循环继续直到maxDateminDate相等。
    5. 返回结果
      • flagn相乘,得到最终的结果,并返回。
4.8 流插入 << 和 流提取 >> 运算符重载

有了日期类那么我们需要打印日期信息该怎么办呢?

  1. 我们可以实现一个 Print 成员函数来实现:
// 打印,const成员函数修饰的是成员函数隐含的this指针,表明不能修改任何成员变量
void Print() const
{cout << _year << "-" << _month << "-" << _day;
}

在这里插入图片描述

但是每次都要调用函数来打印日期是不是太麻烦了,有没有更简单的方法,就像内置类型(int、char等)那样直接使用 cout 打印呢?

  1. 在C++中,对于自定义类型可以重载流插入 << 来实现像内置类型一样的输出操作

在这里插入图片描述
cout 是一个 ostream 类型的对象。

// 流插入<< 重载
ostream& operator<<(ostream& out, const Date& d)
{// 输出格式化字符串到输出流  out << d._year << "-" << d._month << "-" << d._day << endl;// 返回输出流引用以支持链式操作return out;
}

在这里插入图片描述

【思路】:

  1. 定义重载函数:定义一个函数,接受一个ostream引用和一个const Date&引用作为参数。
  2. 输出格式化字符串:在函数内部,使用输出流out来格式化并输出Date对象的年、月、日信息。
  3. 返回输出流引用:为了支持链式输出,函数应返回ostream引用

注意事项:

  • 在使用流插入 << 时,要确保第一个参数是ostream的对象,如果是在重载的时候写成成员函数,编译器就会将第一个参数默认传入this指针,因此只能将其重载成全局函数,传入两个参数,第一个为ostream的对象,第二个为Date类对象。
  • 相应的,重载成了全局函数必然会导致类中的私有成员不能被访问,那么这又该如何呢?这里有两种解决办法:
    1. 创建公有的成员函数getYeargetMonthgetDay,这样就可以通过这些函数去访问私有成员变量,java很喜欢使用这种方式。
    2. 使用友元函数,当一个函数或类被声明为另一个类的友元时,它可以访问该类的所有成员,包括私有成员
      在这里插入图片描述

既然有流插入 >> 运算符的重载,那么必然就有流提取 >> 运算符的重载。

  1. 在C++中,对于自定义类型可以重载流提取 >> 来实现像内置类型一样的输入操作

在这里插入图片描述
cin 是一个 istream 类型的对象。

// 流提取 >> 重载
istream& operator>>(istream& in, Date& d)
{while (1){cout << "请依次输入年 月 日:>";in >> d._year >> d._month >> d._day;if (!d.CheckInvalid()){cout << "亲,你输入了无效日期,请重新输入!" << endl;}else{break;}}// 返回输入流引用以支持链式操作return in;
}

在这里插入图片描述

【思路】

  1. 定义重载函数:定义一个函数,接受一个istream引用和一个Date&引用作为参数。
  2. 输入日期:从输入流中读取年、月、日,并尝试赋值给Date对象。
  3. 验证日期:调用Date对象的CheckInvalid方法来检查输入的日期是否有效。
  4. 错误处理:如果日期无效,则输出错误消息并继续循环,要求用户重新输入。
  5. 返回输入流引用:如果日期有效,则退出循环并返回输入流的引用,以支持链式输入。

5. 日期类源码

5.1 Date.h文件

#pragma once#include <iostream>using namespace std;class Date
{
public:// 获取某年某月的天数int GetMonthDay(int year, int month) const;// 检查日期是否合法bool CheckInvalid();// 全缺省的构造函数Date(int year = 1900, int month = 1, int day = 1){_year = year;_month = month;_day = day;if (!CheckInvalid()){cout << *this << "构造日期非法" << endl;exit(-1);}}// 拷贝构造函数// d2(d1)Date(const Date& d){_year = d._year;_month = d._month;_day = d._day;}// 赋值运算符重载// d2 = d3 -> d2.operator=(&d2, d3)Date& operator=(const Date& d){if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;}// 析构函数~Date(){//cout << "~Date()" << endl;}// 取地址操作符重载Date* operator&(){return this;//return nullptr;}// const取地址操作符重载const Date* operator&()const{return this;//return nullptr;}// 日期+=天数Date& operator+=(int day);// 日期+天数Date operator+(int day);// 日期-天数Date operator-(int day);// 日期-=天数Date& operator-=(int day);// 前置++Date& operator++();// 后置++Date operator++(int);// 后置--Date operator--(int);// 前置--Date& operator--();// >运算符重载bool operator>(const Date& d) const;// ==运算符重载bool operator==(const Date& d) const;// >=运算符重载bool operator >= (const Date& d) const;// <运算符重载bool operator < (const Date& d) const;// <=运算符重载bool operator <= (const Date& d) const;// !=运算符重载bool operator != (const Date& d) const;// 日期-日期 返回天数int operator-(const Date& d);// 打印,const成员函数修饰的是成员函数隐含的this指针,表明不能修改任何成员变量void Print() const{cout << _year << "-" << _month << "-" << _day << endl;}// 友元声明,可以在类的任何位置friend ostream& operator<<(ostream& out, const Date& d);friend istream& operator>>(istream& in, Date& d);
private:int _year;int _month;int _day;
};// 类外声明
ostream& operator<<(ostream& out, const Date& d);
istream& operator>>(istream& in, Date& d);

5.2 Date.cpp 文件

#define _CRT_SECURE_NO_WARNINGS 1#include "Date.h"// 获取某年某月的天数
int Date::GetMonthDay(int year, int month) const
{static int days[13] = { 0,31,28,31,30,31,30,31,30,31,31,30,31 };if (month == 2 && ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0))){return 29;}return days[month];
}// 日期+=天数
Date& Date::operator+=(int day)
{_day += day;while (_day > GetMonthDay(_year, _month)){_day -= GetMonthDay(_year, _month);if (_month == 12){_month = 1;_year++;}else{_month++;}}return *this;
}
// 日期+天数
Date Date::operator+(int day)
{Date temp = *this; // 调用拷贝构造,因为temp不是一个已存在的对象temp += day;return temp;
}
// 日期-天数
Date Date::operator-(int day)
{Date temp = *this;temp -= day;return temp;
}
// 日期-=天数
Date& Date::operator-=(int day)
{while (day >= _day){day -= _day;if (_month == 1){_month = 12;_year--;_day = GetMonthDay(_year, _month);}else{_month--;_day = GetMonthDay(_year, _month);}}_day -= day;return *this;
}// 前置++
Date& Date::operator++()
{*this += 1;return *this;
}
// 后置++
Date Date::operator++(int)
{Date temp = *this;*this += 1;return temp;
}
// 后置--
Date Date::operator--(int)
{Date temp = *this;*this -= 1;return temp;
}
// 前置--
Date& Date::operator--()
{*this -= 1;return *this;
}// >运算符重载
bool Date::operator>(const Date& d) const
{if (_year > d._year)return true;else if (_year == d._year){if (_month > d._month)return true;else if (_month == d._month){if (_day > d._day)return true;}}return false;
}
// ==运算符重载
bool Date::operator==(const Date& d) const
{return _year == d._year&& _month == d._month&& _day == d._day;
}
// >=运算符重载
bool Date::operator >= (const Date& d) const
{return *this > d || *this == d;
}
// <运算符重载
bool Date::operator < (const Date& d) const
{return !(*this >= d);
}
// <=运算符重载
bool Date::operator <= (const Date& d) const
{return !(*this > d);
}
// !=运算符重载
bool Date::operator != (const Date& d) const
{return !(*this == d);
}// 日期-日期 返回天数
int Date::operator-(const Date& d)
{int flag = 1;Date maxDate = *this;Date minDate = d;if (*this < d){flag = -1;maxDate = d;minDate = *this;}int n = 0;while (maxDate != minDate){minDate++;n++;}return flag * n;
}// 检查日期是否合法
bool Date::CheckInvalid()
{if (_year <= 0|| _month < 1 || _month > 12|| _day < 1 || _day > GetMonthDay(_year, _month)){return false;}return true;
}// 流插入 << 重载
ostream& operator<<(ostream& out, const Date& d)
{// 输出格式化字符串到输出流  out << d._year << "-" << d._month << "-" << d._day << endl;// 返回输出流引用以支持链式操作return out;
}
// 流提取 >> 重载
istream& operator>>(istream& in, Date& d)
{while (1){cout << "请依次输入年 月 日:>";in >> d._year >> d._month >> d._day;if (!d.CheckInvalid()){cout << "亲,你输入了无效日期,请重新输入!" << endl;}else{break;}}// 返回输入流引用以支持链式操作return in;
}

总结

🔥💖 此日期类是一个非常适合大家训练自己对运算符重载知识理解和掌握的小项目,它是C++引用传值/传引用返回拷贝构造赋值重载运算符重载const成员函数const修饰参数等知识的一个融合,相信大家在上手练习的过程中能收获颇丰。

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

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

相关文章

Linux Watchdog 机制是什么

当涉及到Linux操作系统的稳定性和可靠性时&#xff0c;Linux Watchdog机制是一个至关重要的议题。该机制旨在监控系统状态&#xff0c;确保在出现问题时采取适当的措施以维持系统的正常运行。本文将深入探讨Linux Watchdog机制的工作原理、应用范围以及如何配置和使用该机制来提…

【leetcode C++】电话号码的字母组合

17. 电话号码的字母组合 题目 给定一个仅包含数字 2-9 的字符串&#xff0c;返回所有它能表示的字母组合。答案可以按 任意顺序 返回。 给出数字到字母的映射如下&#xff08;与电话按键相同&#xff09;。注意 1 不对应任何字母。 题目链接 . - 力扣&#xff08;LeetCode&…

MyBatis 学习(六)之动态 SQL

目录 1 动态 SQL 介绍 2 if 标签 3 where 标签 4 set 标签 5 trim 标签 6 choose、when、otherwise 标签 7 foreach 标签 8 bind 标签 1 动态 SQL 介绍 动态 SQL 是 MyBatis 强大特性之一&#xff0c;极大的简化我们拼装 SQL 的操作。MyBatis 的动态 SQL 是基于 OGNL 的…

腾讯云8核32G22M服务器优惠价格115元1个月、345元3个月

腾讯云8核32G22M服务器优惠价格115元1个月、345元3个月 一张表看懂腾讯云服务器租用优惠价格表&#xff0c;一目了然&#xff0c;腾讯云服务器分为轻量应用服务器和云服务器CVM&#xff0c;CPU内存配置从2核2G、2核4G、4核8G、8核16G、4核16G、8核32G、16核32G、16核64等配置可…

基于springboot+vue的科研工作量管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

基于 HBase Phoenix 构建实时数仓(1)—— Hadoop HA 安装部署

目录 一、主机规划 二、环境准备 1. 启动 NTP 时钟同步 2. 修改 hosts 文件 3. 配置所有主机间 ssh 免密 4. 修改用户可打开文件数与进程数&#xff08;可选&#xff09; 三、安装 JDK 四、安装部署 Zookeeper 集群 1. 解压、配置环境变量 2. 创建配置文件 3. 创建新…

Vue+腾讯地图-实现关键词输入提示功能

不废话&#xff0c;上代码~~~ 效果图&#xff1a; 1、先去腾讯地图后台创建自己的应用获取到应用的 Key 腾讯地图后台地址&#xff1a;腾讯位置服务 - 立足生态&#xff0c;连接未来 创建应用的 Key 如下&#xff1a; 2、在项目中添加腾讯地图API的js插件&#xff0c;如…

学习JAVA的第十四天(基础)

目录 Collection集合 迭代器遍历 增强for遍历 Lambda表达式遍历 List集合 遍历 数据结构 栈 队列 数组 链表 前言&#xff1a; 学习JAVA的第十三天 Collection集合 Collection的遍历方式&#xff1a; 迭代器&#xff08;不依赖索引&#xff09;遍…

Java线程池及Thread相关问题

Java线程池及Thread相关问题 一、Java线程池有哪些核心参数&#xff0c;分别有什么的作用&#xff1f;二、线程池有哪些拒绝策略&#xff1f;三、线程池的执行流程?四、线程池核心线程数怎么设置呢&#xff1f;方式一方式二基本原则 五、ThreadLocal底层是怎么实现的&#xff…

SoraAI优先体验资格注册教程

SoraA1视频工具优先体验资格申请 申请网址&#xff1a;https://openai.com/form/red-teaming-network 申请步骤&#xff1a; 填写基础信息 请使用英文根据内容填写以下内容&#xff0c;名、姓、电子邮件、居住国家、组织隶属关系(如果有)、教育水平 、学位&#xff08;哪个领…

利用Python副业赚钱,看完这篇你就懂了!

Python都可以做哪些副业&#xff1f; 1、兼职处理数据Excel整理数据功能虽然很强大&#xff0c;但在Python面前&#xff0c;曾经统治职场的它也的败下阵来。因为Python在搜集数据整理分析数据的过程中更加便捷&#xff0c;通过几行代码还可以实现自动化操作。 如果你学会Pyth…

指针运算笔试题解析

题目1&#xff1a; int main() { int a[5] { 1, 2, 3, 4, 5 }; int* ptr (int*)(&a 1); printf("%d %d", *(a 1), *(ptr - 1)); return 0; } ptr中存放了整个数组的地址&#xff0c;ptr是int*类型&#xff0c;&a1跳到5的地址后又被强制类…

EasyX的学习2

消息处理——漂亮的按钮(鼠标) 用到的函数 1.消息结构体变量类型&#xff1a;使用ExMessage ExMessage msg{ 0 }; 定义一个变量名为msg的ExMessage结构体变量并初始化为0 2.获取消息函数&#xff1a;peekmessage函数 //获取消息 peekmessage(&msg, EX_MOUSE); 两个参…

【打工日常】使用docker部署在线Photopea用于linux下替代ps

一、Photopea介绍 linux没有ps适配&#xff0c;对于有时候工作来说确实不方便&#xff0c;我找了很久&#xff0c;才找到了一款功能可以跟ps接近的在线软件&#xff0c;使用docker部署就可以了。它是ps的最佳替代品之一&#xff0c;其界面几乎与ps相同&#xff0c;只不过它是在…

MySQL基础-----SQL语句之DCL数据控制语句

目录 前言 一、管理用户 1.查询用户 2.创建用户 3.修改用户密码 4.删除用户 案例 二、权限控制 1.查询权限 2.授予权限 3.撤销权限 案例 前言 本期我们学习SQL语句的最后一部分内容&#xff0c;也就是数据控制语句DCL。DCL英文全称是Data Control Language(数据控制语…

鱼哥赠书活动第12期:《基于React低代码平台开发》

鱼哥赠书活动第12期&#xff1a;《基于React低代码平台开发》 一、React与低代码平台的结合优势二、基于React的低代码平台开发挑战三、基于React的低代码平台开发实践四、未来展望内容简介&#xff1a;作者简介如何阅读&#xff1a;适合阅读人群&#xff1a;赠书抽奖规则:往期…

DMA 链表模式(LLI)深度解析

在进行一次 DMA 读或者写的时候&#xff0c;可以配置多个链表&#xff0c;从而当一个链表的数据传输完成时&#xff0c;会跳到下一个链表的起始地址&#xff0c;并继续传输数据&#xff0c;直到链表的下一个地址为 0。如果 DMA 使能了完成中断&#xff0c;则当 DMA 发送或者接收…

15 实战:Kaggle房价预测 + 课程竞赛:加州2020年房价预测【李沐动手学深度学习课程笔记】

15 实战&#xff1a;Kaggle房价预测 课程竞赛&#xff1a;加州2020年房价预测【李沐动手学深度学习课程笔记】https://zhuanlan.zhihu.com/p/685343754 写在前面&#xff1a;这里格式很乱&#xff0c;代码直接去知乎copy 1 实战Kaggle比赛&#xff1a;预测房价 1.1 实现几个函…

【源码】imx6ull实现触摸屏单点实验-移植tslib和qt

一、本实验实验的器材&#xff1a; 1.正点原子imx6ull的阿尔法开发板v2.2 2.屏幕ALIENTEK 4.3 RGBLCD 二、实验已经移植好的文件&#xff1a; 仓库代码&#xff1a;https://gitee.com/wangyoujie11/atkboard_-linux_-driver.git 1.文件说明 arm-qt.tar.bz2&#xff1a;移植好的…

基于SSM的农业信息管理系统的设计与实现(有报告)。Javaee项目。ssm项目。

演示视频&#xff1a; 基于SSM的农业信息管理系统的设计与实现&#xff08;有报告&#xff09;。Javaee项目。ssm项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&#xff0c;…