【C++杂货铺】运算符重载

在这里插入图片描述

目录

  • 前言
  • 一、运算符重载
  • 二、赋值运算符重载
  • 三、完善日期类
    • 3.1 重载关系运算符
    • 3.2 重载`+`、`+=`
    • 3.3 重载`-`、`-=`
    • 3.4 重载`++`、`--`
    • 3.5 重载`<<`、`>>`
  • 四、const成员
  • 五、取地址及const取地址操作符重载

前言

本文将以日期类为基础,去探寻运算符重载的特性与使用方法,下面先给出日期类的基础定义:

class Date
{
public:Date::Date(int year, int month, int day){if (month > 0 && month <= 12&& day > 0 && day <= GetDay(year, month)){_year = year;_month = month;_day = day;}else{cout << "非法日期" << endl;assert(false);}}
private:int _year;//年int _month;//月int _day;//日
};

备注:拷贝构造函数和析构函数,均可以不写,因为当前日期类的三个成员变量都是内置类型,没有动态申请空间,使用浅拷贝就可以。

一、运算符重载

📖如何比较两个日期的大小?

int main()
{Date d1(2023, 7, 21);Date d2(2023, 6, 21);return 0;
}

现如今,定义了两个日期类的对象d1d2,该如何比较这两个对现象的大小呢?首先想到的是,写一个函数来比较他俩的大小,向下面这样:

//以小于比较为例
bool Less(const Date& x, const Date& y)
{if (x._year > y._year){return false;}else if (x._year == y._year && x._month > y._month){return false;}else if (x._year == y._year && x._month == y._month && x._day > y._day){return false;}else{return true;}	
}

存在的问题:首先这个函数是写在类外面的,意味着,日期类的成员变量如果是private私有的话,在类外面就无法访问,所以在这个函数里面是访问不到对象的年、月、日这三个成员变量,即x._year等都是非法的,要想实现该函数的功能,日期类的成员变量必须是public公有。

其次,在比较两个日期类对象大小的时候,需要写成Less(d1, d2),这和我们平时直接用<符号比较大小,比起来不够直观。

📖为什么日期类不能直接使用<
因为日期类是我们自己定义的,属于一种自定义类型,它的大小比较方式,只有定义它的人知道,而像intdouble等内置类型,是祖师爷创造C++语言时就定好的,祖师爷当然知道该如何比较两个内置类型变量的大小,所以提前帮我们设置好了,我们可以直接用<去比较两个内置类型变量的大小,而至于祖师爷是怎么设置的,这里先埋一个伏笔。

📖运算符重载
为了解决上面Less函数存在的问题,C++引入了运算符重载,它可以让我们直接使用<来比较两个日期类的大小。

运算符重载是具有特殊函数名的函数,也具有返回值类型,函数名字、参数列表、返回值类型都和普通函数类似。

  • 函数名字:关键字operator后面接需要重载的运算符符号。
  • 函数原型:返回值类型 operator操作符(参数列表)
bool operator<(const Date& x, const Date& y)
{if (x._year > y._year){return false;}else if (x._year == y._year && x._month > y._month){return false;}else if (x._year == y._year && x._month == y._month && x._day > y._day){return false;}else{return true;}
}

上面就是对<运算符的一个重载,它的两个形参是Data类型的引用,此时两个日期类对象就可以直接用<来比较大小啦,d1 < d2本质上就是调用运算符重载函数,但是由于上面的运算符重载函数还是写在类外面,所以当日期类的成员变量是private私有的时候,该运算符重载函数还是用不了。

//下面两条语句是等价的本质都是调用运算符重载函数
d1 < d2;
operator<(d1, d2);//d1 < d2的本质

在这里插入图片描述

📖将运算符重载函数写成成员函数
为了解决上面的私有成员变量在类外面无法访问的问题,可以把运算符重载函数写成类的成员函数或者友元,这样就能访问到私有的成员变量,但是友元一般不建议使用,因为友元会破坏封装。

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

上面就是把<运算符重载成类的成员函数,此时参数只有一个,因为<是一个双目运算符,类的非静态成员函数有一个隐藏的形参this指针,所以形参就只需要一个。

//它们俩是等价的
d1 < d2;
d1.operator<(d2);//d1 < d2的本质

在这里插入图片描述
小Tips:一个双目运算符如果重载成类的成员函数,会把它的左操作数传给第一个形参,把右操作数传给第二个形参。以上面为例,this指针接收的是d1的地址,d接收的是d2

📖注意事项:

  • 不能通过连接其他符号来创建新的运算符:比如operator@
  • 重载操作符必须有一个类类型参数。
  • 用于内置类型的运算符,其含义不能改变,例如:内置的+,不能改变其含义。
  • 作为类成员函数重载时,其形参看起来比操作数数目少1,因为成员函数的第一个参数为隐藏的this
  • .*::sizeof? :.这五个运算符不能重载。

二、赋值运算符重载

📖区分赋值运算符重载和拷贝构造

Date d1(2020, 5, 21);
Date d2(2023, 6, 21);
d1 = d2;//需要调用赋值运算符重载
Date d3 = d1;//这里是调用拷贝构造函数
//Date d3(d1);//和上一行等价调用拷贝构造

要区分赋值运算符重载拷贝构造,前者是针对两个已存在的对象,将一个对象的值,赋值给另一个,而后者是用一个已存在的对象去初始化创建一个新对象。

赋值运算符重载格式:

  • 参数类型const T&(T是类型),传引用返回可以提高效率。
  • 返回值类型T&,返回引用可以提高效率,有返回值目的是为了支持连续赋值。
  • 检测是否自己给自己赋值
  • 返回*this:要符合连续赋值的含义。
Date& operator=(const Data& d)
{if (this != &d){_year = d._year;_month = d._month;_day = d._day;}return *this;//出了作用域*this还在,所以可以用引用返回
}

📖只能是类的成员函数
上面的<运算符,最开始我们是在类外面把它重载成全局的,后来为了保证类的封装性,才把它重载成类的成员函数,而赋值运算符天生只能重载成类的成员函数,因为赋值运算符重载属于类的默认成员函数,我们不写,编译器会自动生成,所以,如果我们把赋值运算符重载写在类外面,就会和编译器生成的默认赋值运算符重载发生冲突。

📖编译器生成的干了些什么工作?
用户没有显式实现时,编译器生成的默认赋值运算符重载,对内置类型的成员变量是以值的方式逐字节进行拷贝(浅拷贝),对自定义类型的成员变量,调用其对应类的赋值运算符重载。

三、完善日期类

有了上面的基础,接下来完善一下日期类,重载其他的运算符。

3.1 重载关系运算符

关系运算符有<>==<=>=!=,由于它们之间存在的逻辑关系,可以通过复用来实现,即:要想知道a是否大于b,可以通过判断a是否小于等于b来实现。因此,我们只要写一个<==的比较逻辑,其他的直接复用即可。

📖重载<

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

📖重载==

bool Date::operator==(const Date& d)
{return _year == d._year&& _month == d._month&& _day == d._day;
}

📖重载<=

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

📖重载>

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

📖重载>=

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

📖重载!=

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

3.2 重载++=

有时我们需要知道几天之后的日期,比如我想知道100天后的日期,此时就需要用当前的日期加上100,但是一个日期类型和一个整型可以相加嘛?答案是肯定的,可以通过重载+来实现。运算符重载只规定必须有一个类类型参数,并没有说重载双目操作符必须要两个类型一样的参数。

📖获取某月的天数
日期加天数,要实现日期的进位,即:当当前日期是这个月的最后一天时,再加一天月份就要进一,当当前的日期是12月31日时,再加一天年份就要进一,因此可以先实现一个函数,用来获取当前月份的天数,在每加一天后,判断月份是否需要进位。

int GetDay(int year, int month)//获取某一月的天数
{static int arr[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 arr[month];
}

除了2月,每个月的天数都是固定的,因此可以设置一个数组来存放每个月的天数,并且以月份作为下标,对应存储该月的天数,这种方法类似于哈希映射。这里还有两个小细节,第一个:把数组设置成静态,因为这个函数会重复调用多次,把数组设置成静态,它第一次创建之后,一直到程序结束都还在,可以避免函数调用时重复的创建数组。第二点:把month == 2放在前面判断,因为只有当2月的时候才需要判断是否是闰年,如果不是2月就不用判断是不是闰年。

📖重载+

Date Date::operator+(int x)
{if(x < 0)//天数为负的时候{return *this - (-x);//复用-}/Date tmp = *this;//Date tmp(*this);//和上面等价,都是调用拷贝构造函数tmp._day = _day + x;while (tmp._day > GetDay(tmp._year, tmp._month)){tmp._day = tmp._day - GetDay(tmp._year, tmp._month);tmp._month++;if (tmp._month == 13){tmp._year++;tmp._month = 1;}}return tmp;//
}

注意:要计算a+b的结果,a是不能改变的,因此一个日期加天数,不能改变原本的日期,也就是不能修改this指针指向的内容,所以我们要先利用拷贝构造函数创建一个和*this一模一样的对象,对应上面代码中的tmp,在该对象的基础上去加天数。出了作用域tmp对象会销毁,所以不能传引用返回。

📖重载+=
+=+很像,区别在于+=是在原来是日期上进行修改,即直接对this指针指向的日期做修改,所以我们对上面的代码稍作修改就可以得到+=

Date& Date::operator+=(int x)
{if (x < 0)//当天数为负{return *this -= -x;//复用-=}_day += x;while (_day > GetDay(_year, _month)){_day = _day - GetDay(_year, _month);_month++;if (_month == 13){_year++;_month = 1;}}return *this;
}

小Tips:加一个负的天数,就是算多少天以前的日期,所以,当天数为负的时候,可以复用下面的-=

📖++=之间的复用
可以发现,++=的实现方法十分相似,那是否可以考虑复用呢?答案是肯定的,他俩其中的一方都可以去复用另一方。

+去复用+=

Date Date::operator+(int x)
{/Date tmp = *this;//Date tmp(*this);//和上面等价,都是调用拷贝构造函数tmp += x;return tmp;//
}

+=去复用+

Date& Date::operator+=(int x)
{*this = *this + x;//这里是调用赋值运算符重载return *this;
}

注意:上面的两种复用,只能存在一个,不能同时都去复用,同时存在会出现你调用我,我调用你的死穴。

既然只能存在一个,那到底该让谁去复用呢?答案是:+去复用+=。因为,+=原本的实现过程中并没有调用拷贝构造去创建新的对象,而+原本的实现过程中,会去调用拷贝构造函数创建新的对象,并且是以值传递的方式返回的,期间又会调用拷贝构造。如果让+=去复用+,原本还无需调用拷贝构造,复用后反而还要调用拷贝构造创建新对象,造成了没必要的浪费。

3.3 重载--=

有时我们也需要知道,多少天以前的日期,此时就需要重载-,它的两个操作数分别是日期和天数,其次,我们有时还想知道两个日期之间隔了多少天,这也需要重载-,但此时的两个操作数都是日期。两个-重载构成了函数重载。

📖重载日期-天数
有了上面的经验,我们可以先重载-=,再让-去复用-=即可,日期减天数,就是要实现日期的借位。

Date Date::operator-(int x) 
{Date tmp(*this);return tmp -= x;//复用-=
}

📖重载-=

Date& operator-=(int x)
{if (x < 0)//天数天数小于0{return *this += -x;//复用+=}_day -= x;while (_day <= 0){_month--;if (_month == 0){_month = 12;_year--;}_day += GetDay(_year, _month);}return *this;
}

📖重载日期-日期
日期-日期,它的形参是一个日期对象,计算的结果是两个日期之间的天数,所以返回值是int,要像知道两个日期之间相隔的天数,可以设置一个计数器,让小日期一直加到大日期,就可以知道两个日期之间相隔的天数。

int operator-(const Date& d) 
{Date max = *this;//存放大日期Date min = d;//存放小日期int flag = 1;if (*this < d){max = d;min = *this;flag = -1;}int n = 0;while (max != min){--max;++n;}return n * flag;
}

3.4 重载++--

++--操作符,无论前置还是后置,都是一元运算符,为了让前置和后置形成正确的重载,C++规定:后置重载的时候多增加一个int类型的参数,但是当使用后置,调用运算符重载函数时该参数不用传递,编译器自动传递。

📖重载前置++

//前置++,返回++之后的值
Date& Date::operator++()
{return *this += 1;//直接复用+=
}

📖重载后置++

//后置++,返回加之前的值
Date Date::operator++(int)//编译器会把有int的视为后置++
{Date tmp(*this);*this += 1;//复用+=return tmp;
}

📖重载前置--

Date& operator--()
{return *this -= 1;//复用了-=
}

📖重载后置--

Date operator--(int)
{Date tmp(*this);*this -= 1;//复用了-=return tmp;
}

对比前置和后置可以发现,后置会调用两次拷贝构造函数,一次在创建tmp的时候,另一次在函数返回的时候。而前置则没有调用拷贝构造,所以前置的效率相比后置会高那么一点。

3.5 重载<<>>

同理,对于自定义类型,编译器仍然不知道如何打印,所以要想通过<<去直接打印日期类对象,需要我们对<<运算符进行重载。

📖重识coutcin
我们在使用C++进行输入输出的时候,会用到cincout,它们俩本质上都是对象,cinistream类实例化的对象,coutostream类实例化的对象。

在这里插入图片描述
内置类型可以直接使用<<>>,本质上是因为库中进行运算符重载。而<<>>不用像C语言的printfscanf那样,int对应%dfloat对应%f,是因为运算符重载本质上是函数,对这些不同的内置类型,分别进行了封装,在运算符重载的基础上又实现了函数重载,所以<<>>支持自动识别类型。

在这里插入图片描述

在这里插入图片描述
📖<<为什么不能重载成成员函数
要实现对日期类的<<,要对<<进行重载。但是<<和其他的运算符有所不同,上面重载的所有运算符,为了保证类的封装性,都重载成了类的成员函数,但是<<不行,因为我们平时的使用习惯是cout << d1,前面说过,对于一个双目运算符的重载,它的左操作数会传递给运算符重载函数的第一个形参,右操作数会传递给运算符重载函数的第二个形参,也就是说cout会传递给第一个形参,日期类对象d2会传递给第二个形参,如果运算符重载函数是类的成员函数的话,那么它的第一个形参是默认的this指针,该指针是日期类类型的指针,和cout的类型不匹配,当然也有解决办法,那就是输出一个日期类对象的时候,写成d1 << cout,此时就相当于d1.operator(cout),会把d1的地址传给this指针,形参再用一个ostream类型的对象来接收cout即可,但是这样的使用方式,显然是不合常理的。

📖<<重载成全局函数
正确的做法是,把<<重载成全局函数,此时函数形参就没有默认的this指针,我们可以根据需要来设置形参的顺序,第一个形参用ostream类对象来接收cout,第二个形参用Date日期类对象来接收d1

//重载成全局的
ostream& operator<< (ostream& out, const Date& d)
{out << d._year << "年" << d._month << "月" << d._day << "日" << endl;return out;
}

注意:形参out不能加const修饰,因为我们就是要往out里面写东西,加了const意味着out不能修改。其次为了实现连续的输出,返回值是ostream类型的对象out,因为此时出了作用域out还在,所以可以用引用返回。

因为该运算符重载函数写在全局,默认情况下,在该函数内部是无法访问到日期类的私有成员变量,为了解决这个问题,可以把该运算符重载函数设置成友元函数,或者在类里面写私有成员变量的Get方法(Java常用)。

friend ostream& operator<< (ostream& out, Date& d);

友元函数只需要配合上friend关键字,在日期类里面加上一条声明即可,此时在该函数体就可以使用对象中的私有成员变量。该声明不受类中访问限定符的限制。

📖重载>>
同理,>>也应该重载成全局的。

istream& operator>> (istream& in, Date& d)
{in >> d._year >> d._month >> d._day;return in;
}

注意:两个形参ind都不能用const修饰,前者是因为in本质上是一个对象,在进行流插入的时候,会改变对象里面的一些状态值,而后者是因为,我们就是希望通过流插入往d里面写入数据,所以也不能加const修饰。

小Tips:C++中的流插入和流提取可以完美的支持自定义类型的输入输出,而C语言的scanfprintf只能支持内置类型,这就是C++相较于C语言的一个优势。

四、const成员

将const修饰的成员函数称为const成员函数,const修饰类的成员函数,实际上修饰的是该成员函数隐含的*this,表明该成员函数中不能修改调用该函数的对象中的任何成员。这样一来,不仅普通对象可以调用该成员函数(权限的缩小),const对象也能调用该成员函数(权限的平移)。经过const修饰的成员函数,它的形参this的类型就是:const T* const this

bool Date::operator<(const Date& d) const//用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;}
}

对于所有的关系运算符重载函数,都应该加const修饰,因为它们不会改变对象本身。

📖总结:
并不是所有的成员函数都要加const修饰,要修改对象成员变量的函数,是不能加const修饰的,例如:重载的+=-=等,而成员函数中如果没有修改对象的成员变量,可以考虑加上const修饰,这样不仅普通对象可以调用该成员函数(权限的缩小),const对象也能调用该成员函数(权限的平移)。

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

Date* operator&()
{cout << "Date* operator&()" << endl;return this;
}
const Date* operator&() const
{cout << "const Date* operator&() const" << endl;return this;
}int main()
{Date d1(2023, 7, 22);const Date d2(2023, 7, 22);cout << &d1 << endl;cout << "--------" << endl;cout << &d2 << endl;return 0;
}

在这里插入图片描述
这俩取地址运算符重载函数,又构成函数重载,因为它们的默认形参this指针的类型不同,一个用const修饰了,另一个没有。const对象会去调用const修饰的取地址运算符重载函数。

小Tips:这两个&重载,属于类的默认成员函数,我们不写编译器会自动生成,所以这两个运算符重载一般不需要重载,使用编译器生成的默认取地址的重载即可,只有特殊情况,才需要重载,比如想让别人获取到指定的内容。


🎁结语:
 今天的分享到这里就结束啦!如果觉得文章还不错的话,可以三连支持一下,您的支持就是春人前进的动力!
在这里插入图片描述

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

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

相关文章

Burp Suite---渗透测试工具

文章目录 Burp SuiteBurp Suite入门设置代理HTTP的代理 Proxy&#xff08;代理&#xff09; Burp Suite 是一款集成化的渗透测试工具&#xff0c;包含了很多功能&#xff0c;可以帮助我们高效地完成对Web应用程序的渗透测试和攻击。 Burp Suite由Java语言编写&#xff0c;基于…

【Docker】Docker的数据管理

目录 一、Docker 的数据管理1.1数据卷1.2 数据卷容器1.3端口映射1.4容器互联&#xff08;使用centos镜像&#xff09; 二、Docker镜像的创建2.1基于现有镜像创建2.2&#xff0e;基于本地模板创建2.3 基于Dockerfile 创建联合文件系统&#xff08;UnionFS&#xff09;镜像加载原…

【Vue3】Vue3核心内容(上)

&#x1f380;个人主页&#xff1a;努力学习前端知识的小羊 感谢你们的支持&#xff1a;收藏&#x1f384; 点赞&#x1f36c; 加关注&#x1fa90; 文章目录 常用的Composition APIsetup函数ref函数reactive函数vue3中的响应式原理vue2的响应式Vue3的响应式 reactive对比Refse…

基于FPGA的视频接口之PAL(NTSC)编码

简介 PAL又称帕尔制&#xff0c;是咱们中国早期视频所是使用的视频广播模式&#xff0c;基本上现在的电视都兼容这种视频模式&#xff0c;使用的接口也是传统的BNC插头&#xff0c;有兴趣的伙伴可以看看电视屁股后面是不是有一个单独的BNC接口&#xff0c;百分之98就是支持PAL格…

Folx Pro 5 最好用的Mac磁力链接BT种子下载工具

除了迅雷&#xff0c;还有哪个支持磁力链接下载&#xff1f;Mac电脑如何下载磁力链接&#xff1f;经常有小伙伴问老宅。今天&#xff0c;老宅给大家推荐Folx Pro For Mac&#xff0c;Mac系统超好用的磁力下载工具。 Folx是一款功能强大且易于使用的Mac下载管理器&#xff0c;并…

基于Matlab和V-Rep进行智能机器人手臂拾取和放置(附上完整源码+图片)

文章目录 项目说明完整源码图片下载 项目说明 智能机器人手臂在工业自动化领域中扮演着重要的角色。为了实现机器人手臂的自动化拾取和放置任务&#xff0c;我们可以利用Matlab和V-Rep进行仿真和控制。 Matlab是一种强大的数学计算软件&#xff0c;它提供了丰富的工具箱和函数…

第 109 场 LeetCode 双周赛

A 检查数组是否是好的 暴力: 排序后遍历判断 class Solution { public:bool isGood(vector<int> &nums) {sort(nums.begin(), nums.end());for (int i 0; i < nums.size() - 1; i)if (nums[i] ! i 1)return false;return nums.back() nums.size() - 1;} };B 将…

【转载】elasticsearch 倒排索引原理

由于整型数字 integer 可以被高效压缩的特质&#xff0c;integer 是最适合放在 postings list 作为文档的唯一标识的&#xff0c;ES 会对这些存入的文档进行处理&#xff0c;转化成一个唯一的整型 id&#xff08;这个id是document的id&#xff09;。 再说下这个 id 的范围&…

钉钉和MySQL接口打通对接实战

钉钉和MySQL接口打通对接实战 对接系统钉钉 钉钉&#xff08;DingTalk&#xff09;是阿里巴巴集团专为中国企业打造的免费沟通和协同的多端平台&#xff0c;提供PC版&#xff0c;Web版和手机版&#xff0c;有考勤打卡、签到、审批、日志、公告、钉盘、钉邮等强大功能。 目标系统…

【测试开发】Python+Django实现接口测试工具

PythonDjango接口自动化 引言&#xff1a; 最近被几个公司实习生整自闭了&#xff0c;没有基础&#xff0c;想学自动化又不知道怎么去学&#xff0c;没有方向没有头绪&#xff0c;说白了其实就是学习过程中没有成就感&#xff0c;所以学不下去。出于各种花里胡哨的原因&#xf…

目标检测——SSD模型介绍

目录 SSD网络结构backboneextra部分loc和clsPriorBox层先验框的生成方法loc的预测结果 模型训练正负样本标记损失函数困难样本挖掘 模型预测 SSD网络结构 backbone extra部分 loc和cls PriorBox层先验框的生成方法 loc的预测结果 模型训练 正负样本标记 损失函数 困难样本挖掘…

原神盲盒风格:AI绘画Stable Diffusion原神人物公仔实操:核心tag+lora模型汇总

本教程收集于&#xff1a;AIGC从入门到精通教程汇总 在这篇文章中&#xff0c;我们将深入探讨原神盲盒的艺术风格&#xff0c;以及如何运用AI绘画技术&#xff08;Stable Diffusion&#xff09;——来创造原神角色公仔。我们将通过实践操作让读者更好地理解这种技术&#xff0…

【Java基础教程】(十八)包及访问权限篇 · 下:Java编程中的权限控制修饰符、单例设计模式 (Singleton)和多例设计模式的综合探析~

Java基础教程之包及访问权限 下 本节学习目标1️⃣ 访问控制权限2️⃣ 命名规范3️⃣ 单例设计模式 (Singleton)4️⃣ 多例设计模式 本节学习目标 掌握Java 中的4种访问权限&#xff1b;掌握Java 语言的命名规范&#xff1b;掌握单例设计模式与多例设计模式的定义结构&#x…

界面控件DevExpress WPF数据编辑器组件,让数据处理更灵活!(二)

界面控件DevExpress WPF编辑器库可以帮助用户提供直观的用户体验&#xff0c;具有无与伦比的运行时选项和灵活性。WPF数据编辑器提供了全面的掩码和数据验证支持&#xff0c;可以独立使用&#xff0c;也可以作为容器控件(如DevExpress WPF Grid和WPF TreeList)中的单元格编辑器…

【Kubernetes部署篇】ingress-nginx高可用架构实施部署

文章目录 一、环境说明二、实施过程1、部署Ingress Controller2、安装并配置Nginx3、安装并配置Keepalived3、测试keepalived主备切换 三、创建Ingress规则&#xff0c;测试七层转发 一、环境说明 1、环境说明&#xff1a; IP地址主机名称备注16.32.15.201node-1K8S节点16.32…

共享汽车管理系统nodejs+vue

语言 node.js 框架&#xff1a;Express 前端:Vue.js 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat 开发软件&#xff1a;VScode 前端nodejsvueelementui, 共享汽车管理系统的系统管理员可以管理用户&#xff0c;可以对用户信息修改删除以及查询操作。具体界面的展…

微信小程序02

组件 组件生命周期 小程序组件生命周期&#xff0c;写在lifetimes中&#xff1a; created &#xff1a; 当组件实例刚刚被创建&#xff0c;&#xff0c;不能调用 this.setData()attached &#xff1a; 组件实例进入 页面节点树时 执行detached&#xff1a; 组件实例 从 页面…

Django项目开发快速入门

Django项目开发快速入门 生成Django项目编写module后台管理系统admin自定义管理页面视图函数使用Django模板 生成Django项目 现在cmd中使用命令安装Django框架 pip install django3.2使用命令生成项目 django-admin startproject DjStore使用命令生成应用 python .\manage.…

Redis应用(2)——Redis的项目应用(一):验证码 ---> UUID到雪花ID JMeter高并发测试 下载安装使用

目录 引出Redis的项目应用&#xff08;一&#xff09;&#xff1a;验证码1.整体流程2.雪花ID1&#xff09;UUID&#xff08;Universally Unique Identifier&#xff0c;通用唯一识别码&#xff09;2&#xff09;Twitter 的雪花算法&#xff08;SnowFlake&#xff09; 雪花ID优缺…

【Java】一个简单的接口例子(帮助理解接口+多态)

要求&#xff1a; 请实现笔记本电脑使用USB鼠标、USB键盘的例子 1. USB 接口&#xff1a;包含打开设备、关闭设备功能 2. 笔记本类&#xff1a;包含开机功能、关机功能、使用 USB 设备功能 3. 鼠标类&#xff1a;实现 USB 接口&#xff0c;并具备点击功能 4. 键盘类&am…