【类和对象】日期类总结

日期类是我们学习类和对象这部分知识的常客,本篇博客我们就对日期类成员函数进行全面总结

目录

一、一览Date.h函数声明

二、Date.cpp逐部分实现

一、流插入与流提取运算符重载

二、日期之间比较大小相等运算符重载

1.  >

2.  ==

3.  >=

4.  !=

5.  <

6.  <=

三、日期与天数运算操作符重载

1.获取某年某月的天数的函数

2.日期+=天数

3.日期+天数

4.日期-=天数

5.日期-天数

四、赋值运算符重载函数

五、日期本身运算符重载函数

1.前置++

2.后置++

3.前置--

4.后置--

5.日期-日期

 六、取地址运算符重载

七、日期类细节总结

三、日期类代码汇总(声明定义分离)

Date.h

Date.cpp

Test.cpp


一、一览Date.h函数声明

 我们将要实现的日期类关键函数分成6部分来展开讲解

#include<iostream>
using namespace std;
class Date
{//1.流插入与流提取运算符重载friend ostream& operator<<(ostream& out, const Date& d);friend istream& operator>>(istream& in, Date& d);public://获取某年某月的天数int GetMonthDay(int year, int month) const;//默认构造函数Date(int year = 1, int month = 1, int day = 1);//打印函数void Print() const; //2.日期之间比较大小相等运算符重载 //>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;//3.日期与天数运算操作符重载//日期+=天数Date& operator+=(int day);//日期+天数(复用日期+天数)Date operator+(int day) const;//日期-=天数Date& operator-=(int day);//日期-天数Date operator-(int day) const;//4.赋值运算符重载函数Date& operator=(const Date& d);//5.日期本身运算符重载函数//前置++Date& operator++();//后置++Date operator++(int);//前置--Date& operator--();//后置--Date operator--(int);//日期-日期int operator-(const Date& d) const;//6.取地址运算符重载Date* operator&();const Date* operator&()const;private:int _year;int _month;int _day;
};

二、Date.cpp逐部分实现

一、流插入与流提取运算符重载

我们已经清楚,流插入与流提取操作符平时都是这么用的:

#include<iostream>
using namespace std;
int main()
{int n = 0;cin >> n;cout << n;
}

可以看到,cin与cout都是写操作符左边的,变量在右边

而成员函数默认的this指针都是第一个形参,这就导致要把运算符重载函数设定为成成员函数的话,cin与cout的使用习惯要改变一下;

#include<iostream>
using namespace std;
class Date
{
public:void operator>>(istream& in){in >> _year >> _month >> _day;}void operator<<(ostream& out){out << _year << "年" << _month << "月" << _day << "日";}
private:int _year;int _month;int _day;
};
int main()
{Date a;a >> cin;a << cout;
}

但是这样书写cin与cout明显不符合使用习惯和价值,因此我们还是选择把流插入与流提取操作符重载成全局函数, 而全局函数又不能直接访问类中的私有成员,这时要用到友元函数的声明;

#include<iostream>
using namespace std;
class Date
{//有元函数的声明friend void operator>>(istream& in, Date& d);friend void operator<<(ostream& out, const Date& d);
private:int _year;int _month;int _day;
};
void operator>>(istream& in, Date& d)
{in >> d._year >> d._month >> d._day;
}
void operator<<(ostream& out, const Date& d)
{out << d._year << "年" << d._month << "月" << d._day << "日";
}
int main()
{Date a;cin >> a;cout << a;
}

为了支持连续输入与输出,函数的返回值得改一改~

#include<iostream>
using namespace std;
class Date
{//有元函数的声明friend istream& operator>>(istream& in, Date& d);friend ostream& operator<<(ostream& out, const Date& d);
private:int _year;int _month;int _day;
};
istream& operator>>(istream& in, Date& d)
{in >> d._year >> d._month >> d._day;return in;
}
ostream& operator<<(ostream& out, const Date& d)
{out << d._year << "年" << d._month << "月" << d._day << "日";return out;
}
int main()
{Date a;Date b;cin >> a >> b;cout << a << endl << b;
}

二、日期之间比较大小相等运算符重载

需要实现的运算有  >   ==   >=   !=   <  <=

我们只需要具体实现前两个运算,然后其他函数复用前两个即可(充分体现this指针的价值)

1.  >

#include<iostream>
using namespace std;
class Date
{
public:bool operator>(const Date& d) const{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;}}
private:int _year;int _month;int _day;
};

2.  ==

#include<iostream>
using namespace std;
class Date
{
public:bool operator==(const Date& d) const{if (_year == d._year && _month == d._month && _day == d._day){return true;}else{return false;}}
private:int _year;int _month;int _day;
};

3.  >=

bool Date::operator>=(const Date& d) const
{return *this > d || *this == d;
}

4.  !=

bool Date::operator!=(const Date& d) const
{return !(*this == d);
}

5.  <

bool Date::operator<(const Date& d) const
{return !(*this >= d);
}

6.  <=

bool Date::operator<=(const Date& d) const
{return !(*this > d);
}

三、日期与天数运算操作符重载

1.获取某年某月的天数的函数

 数组保存了平年每个月的天数,闰年二月直接返回29天,其余情况就返回数组中某个月天数

int GetMonthDay(int year, int month)
{const static int MonthArray[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;}return MonthArray[month];
}

2.日期+=天数

1.直接把天数加到_day上,天满了,月++,月满了,年++;

2.为了支持day为负数的操作,复用一会要实现的 -=

Date& Date::operator+=(int day)
{if (day < 0){return *this -= (-day);}_day += day;while (_day > GetMonthDay(_year, _month)){_day -= GetMonthDay(_year, _month);++_month;if(_month == 13){++_year;_month = 1;}}return *this;
}

3.日期+天数

日期+天数 意思是日期本身不变,返回加之后的结果,复用+=即可

Date Date::operator+(int day) const
{Date tmp(*this); //拷贝一份放到类tmp中//等价于 Date tmp = *this;tmp += day;return tmp;
}

4.日期-=天数

1.让_day减去天数,day<=0,月--,若月==0,年--,月归为12,最后_day加上该年该月天数

2.为了支持day为负数的操作,复用 +=

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

5.日期-天数

Date Date::operator-(int day) const
{Date tmp(*this);tmp -= day;return tmp;
}

四、赋值运算符重载函数

Date& Date::operator=(const Date& d)
{//避免自己给自己赋值if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;
}

五、日期本身运算符重载函数

1.前置++

Date& Date::operator++()
{*this += 1;return *this;
}

2.后置++

1.后置++--加一个int参数进行占位,跟前置++构成函数重载进行区分

2.后置++返回的是++之前的值,因此我们拷贝构造了tmp保存++之前的值,返回tmp

Date Date::operator++(int)
{Date tmp(*this);*this += 1;return tmp;
}

3.前置--

Date& Date::operator--()
{*this -= 1;return *this;
}

4.后置--

Date Date::operator--(int)
{Date tmp(*this);*this -= 1;return tmp;
}

5.日期-日期

 日期-日期可能是正数,也可能是负数,我们事先不知道谁大谁小,因此假定了一下~,利用变量flag标识最后的正负

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

 六、取地址运算符重载

Date* Date::operator&()
{return this; //return nullptr; ---不想被取地址
}
const Date* Date::operator&()const
{return this;
}

七、日期类细节总结

1.有的函数后面加了const,有的没有加const,取决于函数内部是否需要改变日期类,+=,-=等操作都是要改变日期类本身的,而+ - 等操作是不改变的

2.不需要在函数内部改变日期类的时候尽量都加const,否则很容易在调用时造成权限放大~

3.非const成员可以调用const函数,const成员不能调用非const函数;非const函数内部可以调用const函数, const函数内部不能调用非const函数

4.拷贝构造函数和赋值运算符重载函数本质是不一样的,都有存在的价值~

  ···拷贝构造函数是用一个已经存在的对象拷贝构造一个要创建的对象

  ···赋值运算符重载函数是把一个已经存在的对象赋值给另一个存在的对象

三、日期类代码汇总(声明定义分离)

Date.h

#include<iostream>
using namespace std;
class Date
{//友元声明friend ostream& operator<<(ostream& out, const Date& d);friend istream& operator>>(istream& in, Date& d);
public://获取某年某月的天数int GetMonthDay(int year, int month) const;//默认构造函数Date(int year = 1, int month = 1, int day = 1);//打印函数void Print() const; //加const目的是为了解决权限放大问题//总结一下:只读函数可以加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;//<=bool operator<=(const Date& d) const;//日期+=天数Date& operator+=(int day);//日期+天数(复用日期+天数)Date operator+(int day) const;//日期-=天数Date& operator-=(int day);//日期-天数Date operator-(int day) const;//赋值运算符重载函数Date& operator=(const Date& d);//前置++Date& operator++();//后置++Date operator++(int);//前置--Date& operator--();//后置--Date operator--(int);//日期-日期int operator-(const Date& d) const;//函数之间的互相调用//非const可以调用const---权限缩小//const不能调用非const---权限放大//取地址运算符重载---日常自动生成的就可以//如果不想被取到地址,可以手动实现取地址运算符重载函数Date* operator&();const Date* operator&()const;//无法重载成成员函数//流插入运算符重载函数//void operator<<(ostream& out);//流提取运算符重载函数//void operator>>(istream& in);
private:int _year;int _month;int _day;
};//void operator<<(ostream& out, const Date& d);
//void operator<<(ostream& out, const Date& d);

Date.cpp

#include "Date.h"int Date::GetMonthDay(int year, int month) const
{const static int MonthArray[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;}return MonthArray[month];
}Date::Date(int year, int month, int day)
{_year = year;_month = month;_day = day;//检查日期是否合法if (month < 1 || month >12 || day > GetMonthDay(year, month)){cout << "日期非法" << endl;}
}void Date::Print() const
{cout << _year << "年" << _month << "月" << _day << "日" << endl;
}bool Date::operator>(const Date& d) const
{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;}
}bool Date::operator==(const Date& d) const
{if(_year == d._year && _month == d._month && _day == d._day){return true;}else{return false;}
}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);
}//+ 复用 += (效率更高) --- +的实现中有两次拷贝
Date& Date::operator+=(int day)
{if (day < 0){return *this -= (-day);}_day += day;while (_day > GetMonthDay(_year, _month)){_day -= GetMonthDay(_year, _month);++_month;if(_month == 13){++_year;_month = 1;}}return *this;
}Date Date::operator+(int day) const
{Date tmp(*this); //拷贝一份放到类tmp中//等价于 Date tmp = *this;tmp += day;return tmp;
}// += 复用 + (效率偏低) --- +=的实现 两次拷贝(调用+的两次拷贝) + 一次赋值 
//Date Date::operator+(int day)
//{
//	Date tmp(*this);
//	tmp._day += day;
//	while (tmp._day > GetMonthDay(_year, _month))
//	{
//		tmp._day -= GetMonthDay(_year, _month);
//		++tmp._month;
//		if (tmp._month == 13)
//		{
//			++tmp._year;
//			tmp._month = 1;
//		}
//	}
//	return tmp;
//}
//
//Date& Date::operator+=(int day)
//{
//	法一:
//	//Date ret = *this + day;
//	//*this = ret; //赋值重载
//
//	//法二:
//	*this = *this + day; //赋值重载
//	return *this;
//}
/Date& Date::operator-=(int day)
{if (day < 0){return *this += (-day);}_day -= day;while (_day <= 0){_month--;if (_month == 0){_year--;_month = 12;}_day += GetMonthDay(_year, _month);}return *this;
}Date Date::operator-(int day) const
{Date tmp(*this);tmp -= day;return tmp;
}//赋值运算符重载函数---返回值可以是void, 但最好是Date&, 这样才能支持连续赋值
Date& Date::operator=(const Date& d)
{//避免自己给自己赋值if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;
}//前置++
Date& Date::operator++()
{*this += 1;return *this;
}//后置++--加一个int参数进行占位,跟前置++构成函数重载进行区分
//本质后置++调用,编译器进行特殊处理
Date Date::operator++(int)
{Date tmp(*this);*this += 1;return tmp;
}//前置--
Date& Date::operator--()
{*this -= 1;return *this;
}
//后置--
Date Date::operator--(int)
{Date tmp(*this);*this -= 1;return tmp;
}//日期-日期
int Date::operator-(const Date& d) const
{Date max = *this;Date min = d;int flag = 1;if (*this < d){max = d;min = *this;flag = -1;}int n = 0;while (min != max){min++;n++;}return n * flag;
}//取地址运算符重载函数
Date* Date::operator&()
{return this; //return nullptr; ---不想被取地址
}
const Date* Date::operator&()const
{return this;
}//不太符合使用习惯的写法
流插入运算符重载函数
//void Date::operator<<(ostream& out)
//{
//	out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
//}
//
流提取运算符重载函数
//void Date::operator>>(istream& in)
//{
//	in >> _year >> _month >> _day;
//}//有元函数写法
//流插入运算符重载函数
//void operator<<(ostream& out, const Date& d)
//{
//	out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
//}
流提取运算符重载函数
//void operator>>(istream& in, Date& d)
//{
//	in >> d._year >> d._month >> d._day;
//}//支持连续的流插入与流提取
ostream& operator<<(ostream& out, const Date& d)
{out << d._year << "年" << d._month << "月" << d._day << "日" << endl;return out;
}
//流提取运算符重载函数
istream& operator>>(istream& in, Date& d)
{in >> d._year >> d._month >> d._day;return in;
}

Test.cpp

#include "Date.h"
void TestDate1() //测试运算符重载函数
{Date d1(2023, 7, 23);Date d2(2023, 8, 1);cout << (d1 > d2) << endl; //等价于 d1.operator>(d2);cout << (d1 == d2) << endl; //等价于 d1.operator==(d2);cout << (d1 >= d2) << endl; //等价于 d1.operator>=(d2);cout << (d1 != d2) << endl; //等价于 d1.operator!=(d2);cout << (d1 < d2) << endl; //等价于 d1.operator<(d2);cout << (d1 <= d2) << endl; //等价于 d1.operator<=(d2);
}void TestDate2() //测试 += 与 +
{//+=Date d1(2023, 7, 23);Date ret1 = d1 += 150;ret1.Print();//+Date d2(2023, 8, 1);Date ret2 = d2 + 33; //等价于Date ret2(d7 + 33);ret2.Print();
}void TestDate3() //测试 -= 与 -
{//-=Date d1(2023, 7, 23);Date ret1 = d1 -= 33;ret1.Print();//-Date d2(2023, 1, 13);Date ret2 = d2 - 23;ret2.Print();
}void TestDate4() // 测试 += -= + - 负数
{Date d1(2023, 8, 1);Date ret1 = d1 += -100;ret1.Print();Date d2(2023, 8, 1);Date ret2 = d2 -= -100;ret2.Print();
}void TestDate5() //测试拷贝构造函数与赋值运算符重载函数
{//拷贝构造和赋值重载是有区别的//拷贝构造:一个已经存在的对象去初始化另一个要创建的对象Date d3(2023, 7, 31);Date d4(d3);//赋值重载:两个已存在对象进行拷贝Date d5(2023, 8, 1);Date d6;d6 = d5; //等价于d6.operator=(d5);//连续赋值d3 = d6 = d5; // d6 = d5 表达式的返回值是d6d3.Print();
}void TestDate6() //测试前置++,后置++,前置--,后置--
{Date d1(2023, 7, 31);Date ret1 = ++d1;  //可以显式调用 Date ret1 = d1.operator++();d1.Print();ret1.Print();Date d2(2023, 7, 31);Date ret2 = d2++;//可以显式调用 Date ret2 = d2.operator++(int);d2.Print();ret2.Print();Date d3(2023, 7, 31);Date ret3 = --d3;d3.Print();ret3.Print();Date d4(2023, 7, 31);Date ret4 = d4--;d4.Print();ret4.Print();
}void TestDate7() //测试日期-日期
{Date d1(2023, 8, 1);Date d2(2004, 3, 19);cout << d1 - d2 << endl;
}void TestDate8() //测试权限问题
{const Date d1; d1.Print();  //权限平移Date d2;d2.Print();  //权限缩小
}void TestDate9() //测试取地址运算符重载函数
{Date d1(2023, 8, 1);cout << &d1 << endl; //编译器调用了取地址运算符重载const Date d2(2023, 8, 2);cout << &d2 << endl; //编译器调用了取地址运算符重载
}void TestDate10() //测试流插入与流提取重载函数
{测试流提取//Date d1(2023, 8, 1);cout << d1; //如何直接使用 << 输出自定义类型对象 ---运算符重载函数//d1 << cout;测试流插入//Date d2;//d2 >> cin;//d2 << cout;//上述写法虽然可以,但是不符合使用习惯和价值//友元函数~//Date d3;//cin >> d3;//cout << d3;//连续插入&连续提取Date d4;Date d5;cin >> d4 >> d5;cout << d4 << d5;
}int main()
{TestDate1();TestDate2();TestDate3();TestDate4();TestDate5();TestDate6();TestDate7();TestDate8();TestDate9();TestDate10();
}

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

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

相关文章

element+vue 之动态form

1.页面部分 <div v-for"(item,index) in formList" :key"index"><el-col :span"6" v-if"item.inputType0"><el-form-item :label"item.conditionName" :prop"item.conditionCode":rules"{req…

Abaqus 中最常用的子程序有哪些 硕迪科技

在ABAQUS中&#xff0c;用户定义的子程序是一种重要的构件&#xff0c;可以将其插入到Abaqus分析中以增强该软件的功能和灵活性。这些子程序允许用户在分析过程中添加自定义材料模型、边界条件、初始化、加载等特定操作&#xff0c;以便更精准地模拟分析中的现象和现象。ABAQUS…

二叉树迭代遍历

PS:以下代码均为C实现 1.二叉树前序遍历 力扣 给你二叉树的根节点 root &#xff0c;返回它节点值的 前序 遍历。 class Solution { public:vector<int> preorderTraversal(TreeNode* root) {stack<TreeNode*> st;vector<int> str;TreeNode* curroot;whil…

简单认识ELK日志分析系统

一. ELK日志分析系统概述 1.ELK 简介 ELK平台是一套完整的日志集中处理解决方案&#xff0c;将 ElasticSearch、Logstash 和 Kiabana 三个开源工具配合使用&#xff0c; 完成更强大的用户对日志的查询、排序、统计需求。 好处&#xff1a; &#xff08;1&#xff09;提高安全…

【leetcode】394. 字符串解码

题目链接&#xff1a;力扣 给定一个经过编码的字符串&#xff0c;返回它解码后的字符串。 编码规则为: k[encoded_string]&#xff0c;表示其中方括号内部的 encoded_string 正好重复 k 次。注意 k 保证为正整数。 你可以认为输入字符串总是有效的&#xff1b;输入字符串中没…

MySQL 主从复制

MySQL主从复制是一种数据复制技术&#xff0c;用于将一个MySQL数据库的数据实时复制到其他MySQL数据库&#xff0c;通常一个作为主数据库&#xff08;master&#xff09;&#xff0c;其他作为从数据库&#xff08;slave&#xff09; 基本工作原理&#xff1a; 主数据库记录所有…

RabbitMQ 教程 | 第10章 网络分区

&#x1f468;&#x1f3fb;‍&#x1f4bb; 热爱摄影的程序员 &#x1f468;&#x1f3fb;‍&#x1f3a8; 喜欢编码的设计师 &#x1f9d5;&#x1f3fb; 擅长设计的剪辑师 &#x1f9d1;&#x1f3fb;‍&#x1f3eb; 一位高冷无情的编码爱好者 大家好&#xff0c;我是 DevO…

【云原生】K8S二进制搭建三:高可用配置

目录 一、部署CoreDNS二、配置高可用三、配置负载均衡四、部署 Dashboard 一、部署CoreDNS 在所有 node 节点上操作 #上传 coredns.tar 到 /opt 目录中 cd /opt docker load -i coredns.tar在 master01 节点上操作 #上传 coredns.yaml 文件到 /opt/k8s 目录中&#xff0c;部…

三、JVM-如何判断对象已死问题

内存模型以及如何判定对象已死问题 体验与验证 2.4.5.1 使用visualvm visualgc插件下载链接 &#xff1a;https://visualvm.github.io/pluginscenters.html 选择对应JDK版本链接—>Tools—>Visual GC 若上述链接找不到合适的&#xff0c;大家也可以自己在网上下载对应…

面试热题(最长回文子串)

给你一个字符串 s&#xff0c;找到 s 中最长的回文子串。 如果字符串的反序与原始字符串相同&#xff0c;则该字符串称为回文字符串 输入&#xff1a;s "babad" 输出&#xff1a;"bab" 最长回文子串以前的博客已经讲过KMP算法以及比较不常见的Manacher算法…

C# 使用堆栈实现队列

232 使用堆栈实现队列 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;、、、&#xff09;&#xff1a;pushpoppeekempty 实现 类&#xff1a;MyQueue void push(int x)将元素 x 推到队列的末尾 int pop()从队列的开头移除并返回元素 in…

Devops系统中jira平台迁移

需求:把aws中的devops系统迁移到华为云中,其中主要是jira系统中的数据迁移,主要方法为在华为云中建立一套 与aws相同的devops平台,再把数据库和文件系统中的数据迁移,最后进行测试。 主要涉及到的服务集群CCE、数据库mysql、弹性文件服务SFS、数据复制DRS、弹性负载均衡ELB。 迁…

【C++】容器篇(五)—— map和set的基本介绍

序言&#xff1a; 在之前&#xff0c;我们已经对STL中的 序列式容器 进行了相关的学习。本期&#xff0c;我将给大家介绍的则是另外一类容器 —— 关联式容器 &#xff01;&#xff01;&#xff01; 目录 &#xff08;一&#xff09;容器回顾 &#x1f4a8;【顺序容器】 &a…

数据结构——红黑树

文章目录 一.红黑树的定义二.红黑树的插入1.红黑树节点的定义2.红黑树的插入操作3.总结&#xff1a; 三.红黑树与AVL树的比较四.检验手写的红黑树五.源码 一.红黑树的定义 红黑树&#xff0c;是一种二叉搜索树&#xff0c;但在每个结点上增加一个存储位表示结点的颜色&#xff…

C++设计模式之访问者模式

C访问者设计模式 文章目录 C访问者设计模式什么是设计模式什么是访问者设计模式该模式有什么优缺点优点缺点 如何使用 什么是设计模式 设计模式是一种通用的解决方案&#xff0c;用于解决特定的一类问题。它是一种经过验证的代码组织方式&#xff0c;可以帮助开发人员更快地实…

STM32 DHT11

DHT11 DHT11数字温湿度传感器是一款含有已校准数字信号输出的温湿度复合传感器。 使用单总线通信 该传感器包括一个电容式感湿元件和一个NTC测温元件&#xff0c;并于一个高性能8位单片机相连&#xff08;模数转换&#xff09;。 DHT11引脚说明 开漏模式下没有输出高电平的能…

Cilium系列-14-Cilium NetworkPolicy 简介

系列文章 Cilium 系列文章 前言 今天我们进入 Cilium 安全相关主题, 介绍 Kubernetes 网络策略以及 CiliumNetworkPolicies 额外支持的内容。 网络策略(NetworkPolicy)的类型 默认情况下&#xff0c;Kubernetes 集群中的所有 pod 都可被其他 pod 和网络端点访问。 网络策…

【并发专题】单例模式的线程安全(进阶理解篇)

目录 背景前置知识类加载运行全过程 单例模式的实现方式一、饿汉式基本介绍源码分析 二、懒汉式基本介绍源码分析改进 三、懒汉式单例终极解决方案&#xff08;静态内部类&#xff09;&#xff08;推荐使用方案&#xff09;基本介绍源码分析 感谢 背景 最近学习了JVM之后&…

解决SVN或GIT忽略提交文件的问题

背景 使用IDEA 的SVN插件提交文件是总是会提交一些不需要提交的文件; 我们可以通过一些简单设置忽略这些文件。 git 在项目根目录新建文本文件&#xff0c;修改后缀为.gitignore 文件中添加内容 *.iml .project .gradle/ .idea/ target/ build/ .vscode/ .settings/ .facto…

Python 开发工具 Pycharm —— 使用技巧Lv.2

pydoc是python自带的一个文档生成工具&#xff0c;使用pydoc可以很方便的查看类和方法结构 本文主要介绍&#xff1a;1.查看文档的方法、2.html文档说明、3.注释方法、 一、查看文档的方法 **方法1&#xff1a;**启动本地服务&#xff0c;在web上查看文档 命令【python3 -m…