C++_运算符重载

news2025/1/21 5:51:27

       

目录

1、运算符重载的定义

2、实现‘<'、'=='的运算符重载

2.1 实现其余的比较运算符

 3、实现‘+’,‘-’,‘+=’,‘-=’等运算符重载

 4、前置、后置‘++’‘--’

 5、流提取、流插入重载

6、赋值重载‘=’

 结语:


前言:

        C++中运算符重载的作用是可以让自定义类型的对象也可以进行相互运算,在c语言中,只有内置类型的变量或者常量可以使用运算符进行简单的计算,比如:定义两个变量int a = 12;int b = 20;可以实现a+b,a-b,a==b....,原因是a和b的类型都是内置类型(即系统提供的数据类型)。若要实现自定义类型对象的运算,只能把这些运算符封装成一个函数,在进行对对象的运算时调用对应的运算符重载函数,实现对象之间的运算。(为什么叫重载,因为在底层中,运算符本身也是一个函数,只是只针对内置类型做运算,现如今我们要实现对象的运算只能写一个专门针对对象的运算符函数,因此两个函数构造重载)

1、运算符重载的定义

        运算符重载是一个函数,他的函数名很特殊是规定好的,即:(关键字)operator+要重载的运算符符号,两者构成函数名。函数名后面跟形参列表,并且具有返回类型,因为不管是那种运算符最后都会得出一个结果,这个结果就是运算符重载的返回值。

        注意以下几点:

        1、运算符重载不能有重载其他符号,比如:@。

        2、运算符重载的形参至少有一个为自定义类型的参数。

        3、这五个符号不能构成运算符重载:.*   ::    sizeof   ?:   .

        4、运算符重载通常是以成员函数的形式出现,因此他的形参参数一般会比实现操作数少1个,原因是第一个参数是隐藏的this指针。

         比如‘<’符号的运算符重载格式如下:

class Date
{
	//this=dt1,dt=dt2
	bool operator<(const Date& dt)const//若想给this指针进行const修饰,则const加到此处
	{

	}
};

int main()
{
    Date dt1;
    Date dt2;

	dt1 < dt2;//等价于:dt1.operator<(dt2)

	return 0;
}

         关系示意图如下:

        由于有些运算符在进行运算时本质是不会改变对象的值(比如:< > >= <= ==),因此在实现这些运算符重载时,用const修饰形参,防止对象被改变,细节上也更加贴近这些运算符。

2、实现‘<'、'=='的运算符重载

        对两个日期类的对象进行比较和判断,具体代码如下:


#include<iostream>
using namespace std;

class Date//日期类
{
public:

	Date(int year, int month, int day)//构造函数初始化
	{
		_year = year;
		_month = month;
		_day = day;
		
	}

	//小于号
    //this=dt1,dt=dt2
	bool operator<(const Date& dt)//bool类型,返回true表示dt1<dt2,false反之
	{
		if (_year < dt._year)
		{
			return true;
		}
		else if (_year == dt._year && _month < dt._month)
		{
			return true;
		}
		else if (_year == dt._year && _month == dt._month && _day < dt._day)
		{
			return true;
		}
		return false;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date dt1(2022, 2, 22);
	Date dt2(2020, 2, 22);
	cout<<(dt1 < dt2)<<endl;
    cout<<(dt2 < dt1)<<endl;    

	return 0;
}

        运行结果:

        从结果可以看到,对象之间也可以使用小于号直接进行比较,比如dt1<dt2的结果是0,表示假,dt1>dt2结果是1,表示真。(为什么编译器在执行语句dt1<dt2时会跳到我们自己实现的运算符函数处,而不是调用系统自己的运算符重载,原因在于调用时实参是自定义类型的对象,而系统自己写的运算符函数的形参类型是内置类型,我们写的运算符函数的形参类型跟调用时刚好匹配,因此会调用我们写的运算符函数。)


        实现判断dt1和dt2是否相等的运算符’==‘,代码如下:


#include<iostream>
using namespace std;

class Date//日期类
{
public:

	Date(int year, int month, int day)//构造函数初始化
	{
		_year = year;
		_month = month;
		_day = day;

	}

	//小于号
	//this=dt1,dt=dt2
	bool operator<(const Date& dt)//bool类型,返回true表示dt1<dt2,false反之
	{
		if (_year < dt._year)
		{
			return true;
		}
		else if (_year == dt._year && _month < dt._month)
		{
			return true;
		}
		else if (_year == dt._year && _month == dt._month && _day < dt._day)
		{
			return true;
		}
		return false;
	}

	//判断是否相等运算符
	bool operator==(const Date& dt)
	{
		return _year == dt._year && _month == dt._month && _day == dt._day;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date dt1(2022, 2, 22);
	Date dt2(2020, 2, 22);
	Date dt3(2022, 2, 22);
	cout << (dt1 == dt2) << endl;
	cout << (dt1 == dt3) << endl;

	return 0;
}

        运行结果:

        从结果可以看到,dt1不等于dt2,所以返回0,表示假。dt1等于dt3,返回1表示真。从主函数中看,是直接用’==‘号对两个对象进行判断的,实则上用’==‘判断两个对象是否相等时,会跳到了我们写的运算符重载处,再进行对对象中各个成员变量的判断与比较(这时候调用的就是编译器自己的运算符函数了,因为都是内置类型的比较),最后返回一个结果给到调用处。

2.1 实现其余的比较运算符

        当实现了‘<'、'=='这两个运算符重载,其余的比较运算符重载想要实现就很简单了,可以直接复用‘<'、'=='这两个运算符重载,完成其他的比较运算符重载。

        比如,‘<='的运算符重载实现如下:

#include<iostream>
using namespace std;

class Date//日期类
{
public:

	Date(int year, int month, int day)//构造函数初始化
	{
		_year = year;
		_month = month;
		_day = day;

	}

	//小于号
	//this=dt1,dt=dt2
	bool operator<(const Date& dt)//bool类型,返回true表示dt1<dt2,false反之
	{
		if (_year < dt._year)
		{
			return true;
		}
		else if (_year == dt._year && _month < dt._month)
		{
			return true;
		}
		else if (_year == dt._year && _month == dt._month && _day < dt._day)
		{
			return true;
		}
		return false;
	}

	//判断相等
	bool operator==(const Date& dt)
	{
		return _year == dt._year && _month == dt._month && _day == dt._day;
	}

	//小于等于
	bool operator<=(const Date& dt)
	{
		return *this < dt || *this == dt;//复用以上两个运算符重载
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date dt1(2022, 2, 22);
	Date dt2(2020, 2, 22);
	Date dt3(2022, 2, 22);
	cout << (dt1 <= dt2) << endl;
	cout << (dt2 <= dt1) << endl;
	cout << (dt1 <= dt3) << endl;

	return 0;
}

        运行结果:

        大概逻辑就是’<='的运算符函数调用了 ‘<'、'=='的运算符函数,因此编译器在执行’<='的运算符函数会跳到 ‘<'、'=='的运算符函数处执行。大大的减少了程序代码量。

        示意图如下:


        因此其余的比较运算符也可以采用以上逻辑, 代码如下:

    //大于等于
	bool operator>=(const Date& dt)
	{
		return !(*this<dt);//复用'<'
	}

	//大于
	bool operator>(const Date& dt)
	{
		return !(*this <= dt);//复用'<='
	}

	//判断不相等
	bool operator!=(const Date& dt)
	{
		return !(*this == dt);//复用'=='
	}

 3、实现‘+’,‘-’,‘+=’,‘-=’等运算符重载

        日期用于加减的场景一般是计算多少天之后的日期是多少,或者多少天之前的日期是多少,以及两个日期之间隔了多少天。比如,计算2022.2.22的100天之后的日期是多少,先得到2月份的总天数,然后用22+100,如果超过了2月份的总天数,则用122减去2月份总天数,并且月份+1,如此循环。

        ‘+=’运算符重载代码:

#include<iostream>
#include<assert.h>
using namespace std;

class Date//日期类
{
public:
	//构造函数初始化
	Date(int year, int month, int day)
	{
		if (month > 0 && month < 13 && (day > 0 
			&& day <= GetMonthDay(year, month)))//检查日期是否合规
		{
			_year = year;
			_month = month;
			_day = day;
		}
		else
		{
			cout << "非法日期" << endl;
			return;
		}

	}

	//计算一个月有多少天
	int GetMonthDay(int year, int month)//year作用是计算闰年
	{
		assert(month > 0 && month < 13);

		int arr[] = { 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];
	}

	void Print()const//打印日期
	{
		cout << _year << "年" << _month << "月" << _day << "日" << endl;
	}

	//日期+=天数
	Date& operator+=(int x)
	{
		if (x < 0)//x为负数,表示减去x,可以调用-=运算符重载
		{
			//*this -= -x;//调用-=时,x要置为正数,否则又表示*this+x,因为此时x是负数
			return *this;
		}
		_day += x;
		while (_day > GetMonthDay(_year, _month))
		{
			_day -= GetMonthDay(_year, _month);
			_month++;
			if (_month > 12)
			{
				_year++;
				_month = 1;
			}
		}
		return *this;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date dt1(2022, 2, 22);
	Date dt2(2020, 2, 22);
	dt1 += 100;
	dt1.Print();

	return 0;
}

        运行结果:

        这里注意的是,‘+=’运算符会改变自身的值,因此d1在+=100后,dt1的值会发生改变,但是‘+’运算符就不会改变dt1的值了,所以在实现‘+’运算符重载时,需要一个载体temp来代替dt1进行+=操作,然后再把再temp+=之后的值返回出去即可,这样一来dt1的值就不会被改变了。


        ‘+’运算符重载代码如下:

#include<iostream>
#include<assert.h>
using namespace std;

class Date//日期类
{
public:
	//构造函数初始化
	Date(int year, int month, int day)
	{
		if (month > 0 && month < 13 && (day > 0 
			&& day <= GetMonthDay(year, month)))//检查日期是否合规
		{
			_year = year;
			_month = month;
			_day = day;
		}
		else
		{
			cout << "非法日期" << endl;
			return;
		}

	}

	//计算一个月有多少天
	int GetMonthDay(int year, int month)//year作用是计算闰年
	{
		assert(month > 0 && month < 13);
		int arr[] = { 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];
	}

	void Print()const//打印日期
	{
		cout << _year << "年" << _month << "月" << _day << "日" << endl;
	}

	//日期+=天数
	Date& operator+=(int x)
	{
		if (x < 0)//x为负数,表示减去x,可以调用-=运算符重载
		{
			//*this -= -x;//调用-=时,x要置为正数,否则又表示*this+x,因为此时x是负数
			return *this;
		}
		_day += x;
		while (_day > GetMonthDay(_year, _month))
		{
			_day -= GetMonthDay(_year, _month);
			_month++;
			if (_month > 12)
			{
				_year++;
				_month = 1;
			}
		}
		return *this;
	}

	//拷贝构造
	Date(const Date& da)
	{
		_year = da._year;
		_month = da._month;
		_day = da._day;
	}

	//日期+天数(复用)
	Date operator+(int x)
	{
		Date temp(*this);//需要调用拷贝构造,创建一个临时变量temp
		temp += x;//让temp复用+=
		return temp;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date dt1(2022, 2, 22);
	Date dt2 = dt1 + 100;
	dt1.Print();
	dt2.Print();

	return 0;
}

        运行结果:

        创建载体的具体操作图: 


        ‘-’与‘-=’的逻辑也相同,代码如下:

    //日期-=天数
	Date& operator-=(int x)
	{
		if (x < 0)//如果-=一个负数,表示+=一个正数,因此可以调用+=函数
		{
			*this += -x;
			return *this;
		}
		_day -= x;
		while (_day <= 0)
		{
			_month--;
			if (_month < 1)
			{
				_year--;
				_month = 12;
			}
			_day += GetMonthDay(_year, _month);
			
		}
		return *this;
	}

	//日期-天数(复用)
	Date& operator-(int x)
	{
		Date temp = *this;//调用拷贝构造创建载体temp
		temp -= x;//让载体进行-=
		return temp;
	}

 4、前置、后置‘++’‘--’

        前置运算符和后置运算符重载的区别在于,前置运算符重载是无形参的,而后置运算符重载的形参必须给一个整形,作用仅仅是为了占位,目的只是为了区分前置和后置,例子如下:

    //前置++
	Date& operator++();

    //后置++
	Date& operator++(int);

        ‘++’运算符表示自增1,因此可以调用‘+=’的重载,前置‘++’运算符重载如下:

#include<iostream>
#include<assert.h>
using namespace std;

class Date//日期类
{
public:
	//构造函数初始化
	Date(int year, int month, int day)
	{
		if (month > 0 && month < 13 && (day > 0
			&& day <= GetMonthDay(year, month)))//检查日期是否合规
		{
			_year = year;
			_month = month;
			_day = day;
		}
		else
		{
			cout << "非法日期" << endl;
			return;
		}

	}

	//计算一个月有多少天
	int GetMonthDay(int year, int month)//year作用是计算闰年
	{
		assert(month > 0 && month < 13);
		int arr[] = { 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];
	}

	void Print()const//打印日期
	{
		cout << _year << "年" << _month << "月" << _day << "日" << endl;
	}

	//日期+=天数
	Date& operator+=(int x)
	{
		if (x < 0)//x为负数,表示减去x,可以调用-=运算符重载
		{
			//*this -= -x;//调用-=时,x要置为正数,否则又表示*this+x,因为此时x是负数
			return *this;
		}
		_day += x;
		while (_day > GetMonthDay(_year, _month))
		{
			_day -= GetMonthDay(_year, _month);
			_month++;
			if (_month > 12)
			{
				_year++;
				_month = 1;
			}
		}
		return *this;
	}

	//++日期
	Date& operator++()
	{
		*this += 1;//复用+=
		return *this;
	}
private:
	int _year;
	int _month;
	int _day;
};

int main()
{
	Date dt1(2022, 2, 22);
	++dt1;
	dt1.Print();

	return 0;
}

        运行结果:

        后置++要遵循先使用才++,因此要返回一个++之前的值,所以需要一个载体temp记录++之前的值,并且返回的是该载体temp,后置++的重载如下: 

//日期++
	Date& Date::operator++(int)
	{
		Date temp = *this;//要调用拷贝构造
		*this += 1;//复用+=
		return temp;
	}

        前置--和后置--的逻辑也一样,只不过把++换成了--,并且复用的是‘-=’运算符重载。‘--’运算符重载如下:

//--日期
	Date& operator--()
	{
		*this -= 1;
		return *this;
	}

	//--日期
	Date& operator--(int)
	{
		Date temp = *this;
		*this -= 1;
		return temp;
	}

 5、流提取、流插入重载

        以上的打印日期的方式都是通过调用Print()函数而实现打印的,因此即使是‘<<’和‘>>’流插入和流提取的符号也可以进行重载,重载之后就可以实现直接通过‘<<’和‘>>’实现对象的打印和输入。

        但是值得注意的是,流提取和流插入的顺序是固定的,即流在左边,打印对象在右边,这时候如果延用this指针则顺序会对不上。所以这里不能使用*this指针作为形参了,通常把流提取和流插入重载写到全局中,但是全局的函数访问不到Date类的私有域,也就无法将年、月、日打印出来。因此如果全局的函数想访问一个类的私有域,只能在该类中进行友元函数(friend)的声明,声明该全局函数是该类的”友元“,就可以在全局函数中访问该类的私有域了。

        流提取、流插入重载代码如下:

#include<iostream>
#include<assert.h>
using namespace std;

class Date//日期类
{
public:

	//友元函数声明
	friend ostream& operator<<(ostream& out, const Date& d);
	friend istream& operator>>(istream& out, Date& d);

	//构造函数初始化
	Date(int year, int month, int day)
	{
		if (month > 0 && month < 13 && (day > 0
			&& day <= GetMonthDay(year, month)))//检查日期是否合规
		{
			_year = year;
			_month = month;
			_day = day;
		}
		else
		{
			cout << "非法日期" << endl;
			return;
		}

	}

	//计算一个月有多少天
	int GetMonthDay(int year, int month)//year作用是计算闰年
	{
		assert(month > 0 && month < 13);
		int arr[] = { 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];
	}

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

//声明在全局
//流插入
ostream& operator<<(ostream& out, const Date& d)
{
	out << d._year << "年" << d._month << "月" << d._day << "日" << endl;
	return out;

}

//流提取
istream& operator>>(istream& out, Date& d)
{
	out >> d._year >> d._month >> d._day;

	if (!(d._month > 0 && d._month < 13 && (d._day > 0 && d._day <= d.GetMonthDay(d._year, d._month))))
	{
		cout << "非法日期" << endl;
		exit(-1);
	}
	return out;
}


int main()
{
	Date dt1(2022, 2, 22);
	cout << dt1 << endl;
	Date dt2(1, 1, 1);
	cin >> dt2;
	cout << dt2 << endl;

	return 0;
}

        运行结果:

6、赋值重载‘=’

        对象也可以通过赋值重载进行对象之间的”赋值“,赋值重载代码如下:

    //赋值重载
	void operator=(const Date& dt)
	{
			_year = dt._year;
			_month = dt._month;
			_day = dt._day;
		
	}

    int main()
    {
        dt1=dt2;
        //但是该赋值重载不支持连续赋值,即dt3=dt1=dt2;
    }

         所以为了可以连续赋值,赋值重载必须返回一个数,如下:

#include<iostream>
#include<assert.h>
using namespace std;

class Date//日期类
{
public:
	//构造函数初始化
	Date(int year, int month, int day)
	{
		if (month > 0 && month < 13 && (day > 0
			&& day <= GetMonthDay(year, month)))//检查日期是否合规
		{
			_year = year;
			_month = month;
			_day = day;
		}
		else
		{
			cout << "非法日期" << endl;
			return;
		}

	}

	//计算一个月有多少天
	int GetMonthDay(int year, int month)//year作用是计算闰年
	{
		assert(month > 0 && month < 13);
		int arr[] = { 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];
	}

	//赋值重载
	Date& operator=(const Date& dt)
	{
		if (this != &dt)
		{
			_year = dt._year;
			_month = dt._month;
			_day = dt._day;
		}

		return *this;
	}

	void Print()const
	{
		cout << _year << "年" << _month << "月" << _day << "日" << endl;
	}

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

int main()
{
	Date dt1(2022, 2, 22);
	Date dt2(1, 1, 1);
	Date dt3(1,1,1);
	dt3 = dt2 = dt1;
	dt1.Print();
	dt2.Print();
	dt3.Print();
	
	return 0;
}

        运行结果:

        最后赋值重载和拷贝构造以及构造三者要区分开:

        对一个还没初始化的实例对象进行传参或者无传参调用构造函数进行初始化叫构造,而用一个已经实例化好的对象去初始化另一个还没被初始化的同类型对象叫拷贝构造。 而赋值重载的两个操作对象必须都是经过初始化了的。

        用上面代码举例:

    //构造
    Date dt1(2022, 2, 22);
	Date dt2(1, 1, 1);
	Date dt3(1,1,1);


	dt3 = dt2 = dt1;//赋值重载
	Date dt4 = dt1;//拷贝构造
	//Date dt4(dt1);//拷贝构造

 结语:

        以上就是关于运算符重载的讲解,运算符重载的本质就是想让对象可以进行和内置类型一样的运算,至于用何种逻辑进行运算就要看重载函数的具体实现了。最后希望本文可以给你带来更多的收获,如果本文对你起到了帮助,希望可以动动小指头帮忙点赞👍+关注😎+收藏👌!如果有遗漏或者有误的地方欢迎大家在评论区补充~!谢谢大家!!( ̄︶ ̄)↗

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

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

相关文章

SwiftUI 趣谈之:绝不可能(Never)的 View!

概览 SwiftUI 的出现极大的解放了秃头码农们的生产力。SwiftUI 中众多原生和自定义视图对于我们创建精彩撩人的 App 功不可没&#xff01; 不过&#xff0c;倘若小伙伴们略微留意过 SwiftUI 框架头文件里的源代码&#xff0c;就会发现里面嵌有一些奇怪 Never 类型&#xff0c…

antdesignpro实现滚动加载分页数据

原理解析&#xff1a;每滚动一次相当于翻页&#xff0c;请求后端时给的页码参数要想办法加1&#xff0c;后端才能根据页码给出相应数据 注意后端收到页码参数之后要准确计算出每页的首行数据&#xff0c;关键逻辑代码&#xff1a; # 根据前端传的页码&#xff0c;进行计算下一…

前端传输formDate格式的数据,后端不能用@RequestBody接收

写了个接口&#xff0c;跟前端对接&#xff0c;前端说怎么一直415的报错 我寻思不对啊&#xff0c;我swagger都请求成功了&#xff0c;后来发现前端一直是以formdata格式提交的数据&#xff0c;这样我其实是可以不加RequestBody的&#xff1b; 知识点&#xff1a; RequestBody…

核方法 : 多项式核函数

一、定义 多项式核函数&#xff1a; 将数据映射到高维空间&#xff0c;从而实现 低维线性不可分 到 高维线性可分 二、核心代码介绍 1、关于 PolynomialFeatures(degree3) &#xff1a; 三次多项式核函数 2、关于 svm_clf.decision_function &#xff1a; 推理 三、代码 …

Redis取最近10条记录

有时候我们有这样的需求&#xff0c;就是取最近10条数据展示&#xff0c;这些数据不需要存数据库&#xff0c;只用于暂时最近的10条&#xff0c;就没必要在用到Mysql类似的数据库&#xff0c;只需要用redis即可&#xff0c;这样既方便也快&#xff01; 具体取最近10条的方法&a…

Python深度学习029:pytorch中常用的模块或方法

PyTorch是一个广泛使用的深度学习库,提供了许多用于构建和训练神经网络的模块和方法。下面是一些PyTorch中常用的模块和方法的简要介绍: PyTorch常用模块和方法 torch 用途:PyTorch的基础模块,提供了多种数学运算功能。常用方法: torch.tensor():创建张量torch.randn():…

12.21 汇编点亮STM32MP157小灯

.text .global _start _start: 时钟使能LDR r0,0x50000A28LDR r1,[r0]ORR r1,r1,#(0x1<<4)ORR r1,r1,#(0x1<<5)ORR r1,r1,#(0x1<<1)STR r1,[r0]配置GPIO模式LDR r0,0x50006000LDR r1,[r0]BIC r1,r1,#(0x2<<20)ORR r1,r1,#(0x1<<20)BIC r1,r1,#(…

线程和进程你真的了解吗?快来看看全面的解析和线程的代码

&#xff08;本篇文章全面的释义了线程和进程&#xff1b;为了方便大家熟练的掌握&#xff0c;内容中引入了详细的代码&#xff1b;欢迎大家学习讨论和批评指正&#xff09; 进程的概念 操作系统(OS)中并发(同时)执行的多个程序任务 进程的特点 宏观并行,微观串行 在一个时…

INS的各类方程---微分方程

INS 会受到误差的扰动&#xff0c; INS 的误差方程进行推导。常用的误差模型有 PHI 角和 PSI 角误差 模型。PHI 角误差模型是基于平台坐标系与真实导航坐标系推导的&#xff0c;误差模型易于理解但形式较为复杂。PSI 角误差模型是基于平台坐标系和计算坐标系推导的&#xff0c;…

【C++】可变参数模板使用总结(简洁易懂,详细,含代码演示)

前言 大家好吖&#xff0c;欢迎来到 YY 滴C系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的《Linux》…

TYPE C 接口知识

1、Type C 概述 Type-C口有4对TX/RX分线&#xff0c;2对USBD/D-&#xff0c;一对SBU&#xff0c;2个CC&#xff0c;另外还有4个VBUS和4个地线。 当Type-C接口仅用作传输DP信号时&#xff0c;则可利用4对TX/RX&#xff0c;从而实现4Lane传输&#xff0c;这种模式称为DPonly模式…

个性化邮件营销策略:提升销售额的有效方法

事实上&#xff0c;电子邮件营销人员一直将个性化视为让受众产生强烈参与感的最佳方式之一。对于很多营销人员来说&#xff0c;实施个性化甚至不再是一种选择&#xff0c;而是培养和吸引潜在客户和联系人的必要条件。因此&#xff0c;今天我们将一起来讨论一些成功电子邮件营销…

【LeetCode刷题笔记】动态规划(一)

376. 摆动序列 解题思路: 1. 动态规划 , 定义 up[i] 表示下标 i 的元素为 结尾 的【 最长上升摆动序列 】的 长度 , down[i] 表示下标 i 的元素为

2016年第五届数学建模国际赛小美赛B题直达地铁线路解题全过程文档及程序

2016年第五届数学建模国际赛小美赛 B题 直达地铁线路 原题再现&#xff1a; 在目前的大都市地铁网络中&#xff0c;在两个相距遥远的车站之间运送乘客通常需要很长时间。我们可以建议在两个长途车站之间设置直达班车&#xff0c;以节省长途乘客的时间。   第一部分&#xf…

【WPF.NET开发】创建模板

本文内容 何时创建 ControlTemplate先决条件创建 ControlTemplate使用模板添加触发器使用 VisualState 使用 Windows Presentation Foundation (WPF)&#xff0c;可以使用自己的可重用模板自定义现有控件的可视结构和行为。 可以对应用程序、窗口和页面全局应用模板&#xff…

【Amazon 实验②】使用缓存策略及源请求策略,用于控制边缘缓存的行为及回源行为

文章目录 1. 了解缓存策略和源请求策略1.1 使用缓存键和缓存策略 实验&#xff1a;使用CloudFront缓存策略和缓存键控制缓存行为 接上一篇文章【Amazon 实验①】使用 Amazon CloudFront加速Web内容分发&#xff0c;我们现在了解和配置如何使用缓存策略及源请求策略&#xff0c;…

JUC AQS ReentrantLock源码分析

AQS java.util.concurrent.locks.AbstractQueuedSynchronizer AQS &#xff08;抽象队列同步器&#xff09;&#xff1a; AbstractQueuedSynchronizer 是什么 来自jdk1.5&#xff0c;是用来实现锁或者其他同步器组件的公共基础部分的抽象实现&#xff0c;是重量级基础框架以及…

java SSM家庭财务管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM家庭财务管理系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代 码和数据库&#xff0c;系统主要采…

Win10 使用 Nmap 扫描 Andorid 设备开放端口

Nmap Nmap 是 网络探测工具和安全/端口扫描器。 官网链接 Nmap参考指南(Man Page) 官网下载地址 Downloading Nmap Nmap 下载安装 到官网下载对应操作系统的安装包&#xff0c; 默认配置&#xff0c;一直下一步安装即可。安装过程中备份下安装路径&#xff0c;后续用到。…

❀My学习Linux小记录之UID和GID(用户ID和组ID)❀

❀My学习Linux小记录之UID和GID&#xff08;用户ID和组ID&#xff09;❀ 目录 ❀My学习Linux小记录之UID和GID&#xff08;用户ID和组ID&#xff09;❀ 用户ID&#xff08;UID&#xff09; 组ID&#xff08;GID&#xff09; 登陆 Linux 系统时&#xff0c;虽然输入的是自己…