类和对象(中)--运算符重载

news2024/11/24 14:32:58

目录

  • 1.运算符重载
    • ①运算符重载的概念
    • ②日期类+和+=运算符重载
  • 2.赋值运算符重载
  • 3. 流插入运算符<<重载
  • 4.Date类实现
  • 5.const成员
  • 6.取地址及const取地址操作符重载

1.运算符重载

大家有没有想过内置类型可以使用的运算符是否自定义类型的成员变量也可以使用呢?

class Date
{
public:
	//构造函数
	Date(int year = 1, int month = 1, int day=1)
	{
		cout << "Date" << endl;
		_year = year;
		_month = month;
		_day = day;
	}
	//拷贝构造函数
	Date(const Date& d)
	{
		cout << "Date(const Date& d)" << endl;
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}

private:
	int _year;
	int _month;
	int _day;
};

正常情况下,让我们比较日期类成员变量的大小(即日期的大小),我们可以用一个函数实现!

//需要把内置类型的成员变量权限设置为公有
bool Less(const Date& x1, const Date& x2)
{
	if (x1._year < x2._year)
	{
		return true;
	}
	else if (x1._year == x2._year && x1._month < x2._month)
	{
		return true;
	}
	else if(x1._year == x2._year && x1._month == x2._month && x1._day < x2._day)
	{
		return true;
	}
	return false;
}
int main()
{
	Date d1(2023, 5, 23);
	Date d2(2023, 4, 26);
	cout << Less(d1, d2) << endl;
	return 0;
}

代码运行的结果为:
在这里插入图片描述
①如果实现比较日期大小函数的人代码素养比较高,他会将这个函数命名为Less,我们看到之后根据结果会知道该函数是判断日期大小的函数;但如果有人将函数名随便命名为Func ,这时我们便不得而知函数的功能,造成可读性差的结果。②相比内置类型直接写成i<j,自定义类型还需要进行传参,相对而言比较麻烦。有没有什么办法能使自定义类型像内置类型一样呢?答案:有的。

①运算符重载的概念

C++为了增强代码可读性引入了运算符重载,运算符重载是具有特殊函数名的函数
也具有返回类型、函数名字以及参数列表,其返回值与参数列表的普通函数类似。
函数名字为:关键字operator后面接需要重载的运算符符号
函数原型:返回类型operator操作符(参数列表)
性质: 1.不能连接其他符号来创建新的操作符:比如operator@
2.重载运算符必须有一个自定义类型的参数,如果有两个以上的参数,其他的参数可以为自定义类型、内置类型
3.用于内置类型的运算符,其含义不能改变,例如:内置类型的+,不能改变其含义
4. .*(访问、解引用)、::(域访问限定符)、sizeof(计算大小) 、?;(三目操作符)、. (成员访问)
注意: 以上5个运算符不能重载,这个经常出现在笔试选择题中

使用运算符重载实现日期类比较大小的函数如下:

bool Date::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 == _month && _day < d._day)
	{
		return true;
	}
	return false;
}

注意: 根据运算符重载的性质,运算符重载有两个及两个以上的参数,有一个是在参数列表里面的形参const Date& d函数中有一个隐藏的this指针,操作符是几个操作数,就有几个参数

调试代码如下:

void Test()
{
	Date d1(2023, 5, 23);
	Date d2(2023, 4, 26);
	d1 < d2;
	d1.operator<(d2);
	//底层汇编代码是一样的
	cout << (d1 < d2) << endl;
	cout << (d1.operator<(d2)) << endl;
}

汇编代码:

	d1 < d2;
00F32281  lea         eax,[d2]  
00F32284  push        eax  
00F32285  lea         ecx,[d1]  
00F32288  call        Date::operator< (0F312F3h)  
	d1.operator<(d2);
00F3228D  lea         eax,[d2]  
00F32290  push        eax  
00F32291  lea         ecx,[d1]  
00F32294  call        Date::operator< (0F312F3h)

代码运行的结果:
在这里插入图片描述

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

②日期类+和+=运算符重载

如果我们知道某个日期经过50天、100天之后的日期是多少?我们使用当前日期,当前月的天数满了,当前月份进位加1,年份进位加1,一年中每个月天数又不一样,而特殊的二月份每逢闰年天数加一,所以我们使用一个函数判断。

int Date::GetMonth(int year, int month)
{
	static int Array[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;
	}
	else
	{
		return Array[month];
	}
}

+=运算符重载实现

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

Date+=加完之后,Date类自身的日期会发生改变,类比内置类型int i=10;i+=10+=运算符重载函数需要返回值,需要做到像内置类型int i=0,j=6;j+=i+=10;一样。

+运算符重载实现

Date Date::operator+(int day)
{
	Date tmp = *this;
	tmp._day += day;
	while (tmp._day > GetMonth(tmp._year, tmp._month))
	{
		tmp._day -= GetMonth(tmp._year, tmp._month);
		tmp._month++;
		if (tmp._month == 13)
		{
			tmp._year++;
			tmp._month = 1;
		}
	}
	return tmp;
}

+运算符重载之后,Date类自身的日期不变,并且返回Date类加上day天数的结果进行赋值,类比内置类型+运算操作int i;int j=i+1;

复用+=运算符实现+运算符重载

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

复用+运算符实现+=运算符重载

//利用+重载改造+=重载
Date& Date::operator+=(int day)
{
	*this = *this + day;
	return *this;
}

建议使用+=运算符重载对+进行改造,拷贝较少,创建对象较少,提高效率。

测试代码如下:

void TestDate2()
{
	Date d1(2023, 4, 26);
	d1.Print();
	d1.operator+=(100);
	d1.Print();
	//Date d2;
	//d2=d1.operator+(100);
	Date d2(d1 + 100);
	d2.Print();

	Date d3 = d1 + 100;//等价Date d2(d1 + 100)
	d3.Print();

代码运行的结果为:
在这里插入图片描述

2.赋值运算符重载

1.赋值运算符重载格式
①参数类型:const Date&,传递引用可以提高效率
②返回类型:Date&返回引用可以提高返回的效率,有返回值目的是为了支持连续赋值
③检测是否自己给自己赋值
④返回*this:要复合连续赋值的含义
2.赋值运算符只能重载成类的成员函数,不能直接定义成全局函数,因为会与类里面生成的赋值函数冲突,且不具备构成函数重载的条件
3.赋值运算符重载函数,用户在没有显示实现时,编译器会默认生成一个默认赋值运算符重载函数以值的方式进行逐字节拷贝,注意:内置类型成员变量是直接赋值的,而自定义类型成员需要调用对应的类赋值运算符重载完成赋值。
DateMyQueue不需要我们实现运算符重载,Stack需要我们自己实现,因为默认生成值拷贝。

	Date& operator=(const Date& d)
	{
		cout << "Date& operator=(const Date& d)" << endl;
		//自己给自己赋值的情况
		if (this != &d)
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}

		//int i,j,k;
		//i=j=k
		//之所以需要返回值(即函数类型不是void),针对像内置类型可以赋值的情况
		//自定义类型也可以做到连续赋值,如果返回类型是void,自定义类型不可能连续赋值
		return *this;
	}

一个栗子:

//赋值运算符重载
//1.赋值运算符重载的格式
#include<iostream>
using namespace std;
class Date
{
public:
	//构造函数
	//类外面不能访问私有和保护、类里面可以访问私有和保护
	Date(int year = 1900, int month = 1, int day = 1)
	{
		cout << "Date(int year = 1900, int month = 1, int day = 1)" << endl;
		_year = year;
		_month = month;
		_day = day;
	}
	Date(const Date& d)
	{
		cout << "Date(const Date& d)" << endl;
		_year = d._year;
		_month = d._month;
		_day = d._day;
	}
	Date& operator=(const Date& d)
	{
		cout << "Date& operator=(const Date& d)" << endl;
		//自己给自己赋值的情况
		if (this != &d)
		{
			_year = d._year;
			_month = d._month;
			_day = d._day;
		}

		int i,j,k;
		//i=j=k
		//之所以需要返回值(即函数类型不是void),针对像内置类型可以赋值的情况
		//自定义类型也可以做到连续赋值,如果返回类型是void,自定义类型不可能连续赋值
		return *this;
	}
	void Print()
	{
		cout << _year << "-" << _month << "-" << _day << endl;
	}
private:
	int _year;
	int _month;
	int _day;
};
int main()
{
	//调用自己写构造函数
	Date d1(2023, 4, 26);
	Date d2(2023, 5, 24);
	//已经存在的两个对象之间的复制拷贝--运算符重载
	d1 = d2;
	//用一个已经存在的对象初始化另一个对象--拷贝构造函数
	Date d3(d1);
	//调用构造函数
	Date d4, d5;
	//调用赋值运算符重载函数
	d5 = d4 = d1;//连续调用
	return 0;
}

代码运行的结果为:
在这里插入图片描述
前置++与后置++运算符重载

//前置++,返回++之后的结果
Date& Date::operator++()
{
	*this += 1;
	return *this;
}
//后置++,返回++之前的结果
//增加int参数不是为了接收值,而是为了占位,与前置++构成重载
Date Date::operator++(int)
{
	Date tmp = *this;
	tmp += 1;
	return tmp;
}

测试代码为:

void TestDate3()
{
	Date d1(2023, 4, 26);
	//都要++,前置++返回++之后的对象,后置++返回++之前的对象
	d1.Print();
	d1++;//d1.operator(int)
	d1.Print();
	++d1;//d1.operator()
	d1.Print();
}

代码运行的结果为:
在这里插入图片描述

3. 流插入运算符<<重载

前面我们所学习的流插入的操作符,会自动识别数据类型,是标准库里帮我们已经实现好的,但仅限于识别内置类型;自定义类型需要我们自己使用运算符重载实现。
在这里插入图片描述

//类里面的声明
ostream& operator<<(ostream& out);
//定义
ostream& Date::operator<<(ostream& cout)
{
	cout << _year << "-" << _month << "-" << _day << endl;
	return cout;
}

测试代码:

void Test1()
{
	Date d1(2023, 7, 23);
	cout << d1 << endl;
}

代码调试运行的结果:
在这里插入图片描述

根据类成员函数定义,第一个参数为*thiscout << d1 << endl;参数顺序不对,d1 << cout;不符合使用习惯,所以编译器会报错。

正确实现方式

//类里面的
friend ostream& operator<<(ostream& out, const Date& d);
//定义
ostream& operator<<(ostream& out, const Date& d)
{
	cout << d._year << "-" << d._month << "-" << d._day << endl;
	return cout;
}

测试代码:

void Test1()
{
	Date d1(2023, 7, 23);
	cout << d1 << endl;
}

代码运行的结果如下:
在这里插入图片描述

把流插入运算符重载函数声明在类里面,使用friend定义为友元函数,并可以使用Date类的私有成员变量,类比输出多个内置类型的数据类型,所以需要返回cout

4.Date类实现

Date.h文件

#pragma once
#include<iostream>
#include<assert.h>
using namespace std;
class Date
{
	friend ostream& operator<<(ostream& out, const Date& d);
	friend istream& operator>>(istream& in, Date& d);
public:
	//构造函数
	Date(int year = 1900, 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;
	}
	//<运算符重载
	bool operator<(const Date& d);
	//==运算符重载
	bool operator==(const Date& d);
	//>=运算符重载
	bool operator<=(const Date& d);
	//>运算符重载
	bool operator>(const Date& d);
	//>=运算符重载
	bool operator>=(const Date& d);
	//!=运算符重载
	bool operator!=(const Date& d);
	int GetMonth(int year, int month);
	//+=运算符重载
	Date& operator+=(int day);
	//+运算符重载
	Date operator+(int day);
	//后置++
	Date& operator++();
	//前置++
	Date operator++(int);
	//-=运算符重载
	Date& operator-=(int day);
	//-运算符重载
	Date operator-(int day);
	//后置--运算符重载
	Date& operator--();
	//前置--
	Date operator--(int);
	//日期天数
	int operator-(const Date& d);
private:
	int _year;
	int _month;
	int _day;
};

Date.cpp文件

#define _CRT_SECURE_NO_WARNINGS 1
#include"Date.h"
//bool Date::operator<(const Date& d)
bool Date::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 == _month && _day < d._day)
	{
		return true;
	}
	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);
}
int Date::GetMonth(int year, int month)
{
	static int Array[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;
	}
	else
	{
		return Array[month];
	}
}
//+=加完之后,自身的值发生改变
//+=需要返回值,需要做到像内置类型int i=0,j=6;j+=i+=10;一样,
//类比内置类型int i=1;i++;
Date& Date::operator+=(int day)
{
	_day += day;
	while (_day > GetMonth(_year, _month))
	{
		_day -= GetMonth(_year, _month);
		_month++;
		if (_month == 13)
		{
			_month = 1;
			_year++;
		}
	}
	return *this;
}
//+加完之后,自变量的值不变,进行赋值,类比内置类型,int i;i+1;
//Date Date::operator+(int day)
//{
//	Date tmp = *this;
//	tmp._day += day;
//	while (tmp._day > GetMonth(tmp._year, tmp._month))
//	{
//		tmp._day -= GetMonth(tmp._year, tmp._month);
//		tmp._month++;	
//		if (tmp._month == 13)
//		{
//			tmp._year++;
//			tmp._month = 1;
//		}
//	}
//	return tmp;
//}
//利用+=重载改造+重载
Date Date::operator+(int day)
{
	Date tmp = *this;
	tmp += day;
	return tmp;
}
//利用+重载改造+=重载
//Date& Date::operator+=(int day)
//{
//	this = *this + day;
//	return *this;
//}
//建议使用+=运算符重载对+进行改造,拷贝较少,创建对象较少,提高效率
//前置++,返回++之后的结果
Date& Date::operator++()
{
	*this += 1;
	return *this;
}
//后置++,返回++之前的结果
//增加int参数不是为了接收值,而是为了占位,与前置++构成重载
Date Date::operator++(int)
{
	Date tmp = *this;
	tmp += 1;
	return tmp;
}
Date& Date::operator-=(int day)
{
	if (day < 0)
	{
		*this += -day;
		return *this;
	}
	_day -= day;
	while (_day <= 0)
	{
		--_month;
		if (_month == 0)
		{
			_month = 12;
			_year--;
		}
		int day1= GetMonth(_year, _month);
		_day += day1;
	}
	return *this;
}
Date Date::operator-(int day)
{
	Date tmp = *this;
	tmp -= day;
	return tmp;
}
Date& Date::operator--()
{
	*this -= 1;
	return *this;
}
Date Date::operator--(int)
{
	Date tmp = *this;
	tmp -= 1;
	return tmp;
}
int Date::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)
	{
		++min;
		++n;
	}
	return flag * n;
}
ostream& operator<<(ostream& out, const Date& d)
{
	cout << d._year << "-" << d._month << "-" << d._day << endl;
	return cout;
}

istream& operator>>(istream& in, Date& d)
{
	int year, month, day;
	in >> year >> month >> day;
	if (month > 0 && month < 13 && day <=
		d.GetMonth(year, month))
	{
		d._year = year;
		d._month = month;
		d._day = day;
	}
	else
	{
		cout << "非法日期" << endl;
		assert(false);
	}
	return in;
}

5.const成员

const修饰的“成员函数”称为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改。
在这里插入图片描述
我们不希望改变类成员函数的私有成员变量,就需要使用const修饰成员函数。

#include<iostream>
using namespace std;
class Date
{
public:
	Date(int year, int month, int day)
	{
		_year = year;
		_month = month;
		_day = day;
	}
	void Print()
	{
		cout << "Print()" << endl;
		cout << "year:" << _year << endl;
		cout << "month:" << _month << endl;
		cout << "day:" << _day << endl << endl;
	}
	void Print() const
	{
		cout << "Print()const" << endl;
		cout << "year:" << _year << endl;
		cout << "month:" << _month << endl;
		cout << "day:" << _day << endl << endl;
	}
private:
	int _year; // 年
	int _month; // 月
	int _day; // 日
};
void Test()
{
	Date d1(2022, 7, 23);
	d1.Print();
	const Date d2(2022, 7, 23);
	d2.Print();
}

代码运行结果:
在这里插入图片描述

①不是所有成员函数都加const,要修改的对象成员变量的函数不能加const修饰;②只要成员函数内部不修改成员修改变量,都应该加const修饰,这样const对象和普通对象都可以调用。

6.取地址及const取地址操作符重载

class Date
{
public:
	Date* operator&()
	{
		cout << "Date* operator&()" << endl;
		return this;
	}
	const Date* operator&()const
	{
		cout << "const Date* operator&()const" << endl;
		return this;
	}
private:
	int _year; // 年
	int _month; // 月
	int _day; // 日
};

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

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

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

相关文章

pyqt5-多行文本区QTextEdit实现鼠标滚轮调整文本大小

核心 在 PyQt5 中&#xff0c;你可以通过处理鼠标滚轮事件来设置 QTextEdit 的字体大小。具体做法是在 QTextEdit 上重新实现 wheelEvent 方法&#xff0c;并根据滚轮方向调整字体大小。 代码 import sys from PyQt5.QtWidgets import * from PyQt5.QtCore import * from PyQt5…

MATLAB 最小二乘法拟合直线点云 方法一 (26)

MATLAB 最小二乘法拟合直线点云 方法一 (26) 一、算法简介二、算法实现1.代码(详细注释)2.结果展示2.1 拟合效果可视化2.2 对比拟合系数与实际值一、算法简介 提供一组点云(x1 y1 )(x2 y2 )(x3 y3 )…等等多个点… 算法自动拟合直线方程 二维点云的直线方程为:y=kx+…

Mac 预览(Preview)丢失PDF标注恢复

感谢https://blog.csdn.net/yaoyao_chen/article/details/127462497的推荐&#xff01; 辛苦用预览在pdf上做的阅读标记&#xff0c;关闭后打开全丢失了&#xff0c;推荐尝试下网站导入文件进行恢复&#xff1a; 直接使用该网页应用PDF Annotation Recovery 或者访问该项目&a…

在 Windows 中通过 WSL 2 高效使用 Docker

大家好&#xff0c;我是比特桃。平时开发中&#xff0c;不免会使用一些容器来跑中间件。而开发者使用的操作系统&#xff0c;大多是Mac OS 、Windows。Docker 为了兼顾这两个平台的用户&#xff0c;推出了 Docker Desktop 应用。Docker Desktop 中的内核还是采用了 Linux 的内核…

swift简单弹幕例子,仿哔哩哔哩

先看例子 每个弹幕的速度都是不一样的&#xff0c;支持弹幕整体开始暂停。 如果弹幕实在是太多了&#xff0c;有个缓冲队列&#xff0c;不停的重试能否显示&#xff0c;保证文字都能显示全&#xff0c;并且每条都能显示。 实现是基于 CADisplayLink 实现的&#xff0c;如此来…

mac使用教程【快速从windows切换为mac,mac快捷键合集】

mac使用教程 1. 安装brew并通过brew安装git 1.1 安装brew 打开终端输入如下命令&#xff1a; % /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install.sh)"选择对应的镜像进行安装 # 例如&#xff1a;输入5&#xff…

了解 3DS MAX 3D摄像机跟踪设置:第 5部分

推荐&#xff1a; NSDT场景编辑器助你快速搭建可二次开发的3D应用场景 1. 创建陨石坑 步骤 1 启动 3ds Max 和 打开本教程最后一部分中保存的文件。 启动 3ds Max 步骤 2 删除所有占位符 从头开始创建陨石坑。 删除所有占位符 步骤 3 创建具有“长度”的平面 段和宽度段各…

如何创建vue2,vue3项目

前提需安装node.js和Vue CLI node.js:https://nodejs.org/zh-cn Vue CLI&#xff1a; npm install -g vue/cli 如何创建一个vue2项目 &#xff08;1&#xff09; 使用cmd终端直接创建 进入到vue项目所创建的目录里&#xff08;我是直接创建在桌面上&#xff09; 选择vue2 …

【mysql】聚簇索引和非聚簇索引(B树和B+树)

博主简介&#xff1a;想进大厂的打工人博主主页&#xff1a;xyk:所属专栏: mysql 目录 一、索引分类 二、索引的数据结构 2.1 B树&#xff1a;改造二叉树 2.2 B树&#xff1a;改造B树 三、Mysql索引实现—InnoDB引擎 3.1 主键索引&#xff08;聚簇索引&#xff09; 3.2 …

如何利用plotly和geopandas根据美国邮政编码(Zip-Code)绘制美国地图

对于我自己来说&#xff0c;该需求源自于分析Movielens-1m数据集的用户数据&#xff1a; UserID::Gender::Age::Occupation::Zip-code 1::F::1::10::48067 2::M::56::16::70072 3::M::25::15::55117 4::M::45::7::02460 5::M::25::20::55455 6::F::50::9::55117我希望根据Zip-…

Python读写csv文件

简介 通过Python内置csv模块&#xff0c;可以读取和写入CSV&#xff08;逗号分隔值&#xff09;文件。 CSV是一种常见的文件格式&#xff0c;通常用于存储表格数据&#xff0c;每行数据由逗号分隔&#xff0c;每个字段可以用引号括起来。 测试文件内容如下 列号,年龄,姓名,性别…

香橙派Zero2安装wiringPi外设库

安装wiringOP库 直接在香橙派上下载 wiringOP 的代码 sudo apt update sudo apt install -y git git clone https://github.com/orangepi-xunlong/wiringOP 如果在香橙派上下载不下来&#xff0c;也可以在通过windows浏览器打开https://github.com/orangepi-xunlong/wiringOP …

【【高级程序设计语言C++】C++多态的概念及原理

1. 多态的概念2. 多态的定义及实现2.1. 多态的条件2.2. 虚函数2.3. 虚函数的重写2.4. 虚函数重写的两个例外2.5. C11的override和final2.6. 重载、重写、重定义的对比 3. 抽象类3.1. 概念3.2. 实现继承和接口继承的对比 4. 多态的原理4.1. 虚函数表4.2. 多态原理4.3. 动态绑定和…

(34)继电器开关

文章目录 前言 34.1 装有IOMCU的自动驾驶仪上的继电器引脚 34.2 通过任务规划器定义继电器引脚 34.3 飞行员控制继电器 34.4 任务控制继电器 34.5 任务规划器控制继电器 前言 "继电器"是自动驾驶仪上的一个数字输出引脚&#xff0c;可在 0V 和 3.3V 或 5V 之间…

商城-学习整理-基础-分布式组件(三)

目录 一、前言二、Spring Cloud&Spring Cloud Alibaba1、Spring Cloud 与Spring Cloud Alibaba简介2、为什么使用Spring Cloud Alibaba3、版本选择4、项目中的依赖 三、Spring Cloud Alibaba-Nacos作为注册中心1、Nacos1&#xff09;、下载 nacos-server2&#xff09;、启动…

【C++ 程序设计】第 1~9 章:常见知识点汇总

目录 一、C 语言简介 二、面向对象的基本概念 三、类和对象进阶 四、运算符重载 五、类的继承与派生 六、多态与虚函数 七、输入/输出流 八、文件操作 九、函数模板与类模板 一、C 语言简介 知识点名称内容C语言的发展简史★★1. C 语言是 C 语言的前身 &…

让GPT人工智能变身常用工具-上

1.密码生成器:GPT为您创建安全密码 想象GPT作为您的个人密码生成器,负责从头到尾为您创建复杂且安全的密码。您只需要告诉他您的密码需求,比如密码的长度,是否包含大写字母、小写字母、数字或特殊字符,他会立即为您生成一个复杂但经过深度设计的密码。 例子: 我希望您…

第八届中国开源年会(COSCon'23)启动!

*海报设计师&#xff1a;朱亿钦&#xff08;居居&#xff09; 一年一度的开源盛会&#xff0c;COSCon23 第八届中国开源年会&#xff0c;将于10月28~29日&#xff0c;在四川成都市高新区菁蓉汇召开&#xff01;本次大会的主题是&#xff1a;“开源&#xff1a;川流不息、山海相…

(css)滚动条样式

(css)滚动条样式 效果&#xff1a; /*滚动条整体样式*/ ::-webkit-scrollbar {width: 2px;/*高宽分别对应横竖滚动条的尺寸*/height: 10px; } ::-webkit-scrollbar-thumb {/*滚动条里面小方块*/border-radius: 10px;width: 2px;height: 60px;background: linear-gradient(0deg,…

leetcode 78. 子集

2023.7.22 本题为回溯系列的一道标准模板题。 如果将回溯问题抽象为一棵树的话&#xff0c;那么之前的组合、分割问题都是为了找到这棵树的叶子节点&#xff0c;而子集是要找到这棵树的所有节点。 然后要注意&#xff0c;子集是无序的&#xff0c;即{1&#xff0c;2}和{2&#…