C++运算符重载总结

一、C++操作符重载的意义

1、当运算符作用于类类型的运算对象时,可以通过运算符重载重新定义该运算符的含义。
2、在模板编程实现的泛型编程中,对不同类型实现相同的语义,各自类通过操作符重载实现对应语义。
例如:由模板类自己定义大小关系。

// FUNCTION TEMPLATE _Min_value
template<class _Ty>
	_Post_equal_to_(_Right < _Left ? _Right : _Left)
	constexpr const _Ty& _Min_value(const _Ty& _Left, const _Ty& _Right)
		_NOEXCEPT_COND(_NOEXCEPT_OPER(_Right < _Left))
	{	// return smaller of _Left and _Right
	return (_Right < _Left ? _Right : _Left);
	}

		// FUNCTION TEMPLATE _Max_value
template<class _Ty>
	_Post_equal_to_(_Left < _Right ? _Right : _Left)
	constexpr const _Ty& _Max_value(const _Ty& _Left, const _Ty& _Right)
		_NOEXCEPT_COND(_NOEXCEPT_OPER(_Left < _Right))
	{	// return larger of _Left and _Right
	return (_Left < _Right ? _Right : _Left);
	}

二、哪些运算符能够重载?哪些不可重载?哪些不该被重载?

1、能够被重载的运算符

//	new delete new[] delete[]	//内存分配的接管作用
//	+ - * / % 
//	^ & | ~ 
//	! = < > 
//	+= -= *= /= %= <= >= 
//	<< >> <<= >>=
//	== != <= >=
//	&& ||
//	++ -- //分前置和后置
//	,
//	->* -> () []				//通过指针取成员指针、通过指针取成员、强制类型转换、数组取下标

2、不可重载的运算符

//	.			通过对象(结构体)取成员
//	.*			通过对象取成员指针
//	::			作用域分辨符
//	?:			条件运算符
//	sizeof		计算数据大小运算符

3、不该被重载的运算符

//	,			//逗号表达式
//	&			//取地址
//	&& ||		//逻辑与逻辑或

三、运算符的重载规则

1、重载后运算符的优先级与结合性不会改变。
2、不能改变原有运算符操作数的个数。
3、不能重载C++没有的运算符。
4、不能改变运算符的原有语义。

四、运算符函数重载的两种形式

1、重载为类的成员函数(隐含参数this)
2、重载为类的非成员函数(一般为友元函数)。

五、什么时候应该重载为类的成员函数运算符,什么时候应该重载为类的友元函数运算符?

1、一般,单目运算符最好重载为类的成员函数,双目运算符则最好重载为友元函数。
2、一些双目运算符(=,(),[],->)不能重载为类的友元函数。
3、类型转换函数只能定义一个类的成员函数。
4、若一个运算符的操作需要修改对象的状态,选择重载成员函数较好。
5、若运算符所需操作数(尤其是第一个操作数)期望有隐式的类型转换,则只能选择友元函数。
6、当运算符函数是一个成员函数时,最左边的操作数(或者只有最左边的操作数)必须是运算符类的一个类对象(包括引用)。如果左边操作数必须是一个不同类的对象,或者一个基本数据类型的对象,该运算符必须作为一个友元函数来实现。
7、当需要考虑运算符的运算具有可交互性,选择重载为友元函数。

六、运算符重载实现的示例

Complex.h

#pragma once
#include <iostream>
#include <cmath>

class Complex
{
private:
	double re, im;

public:
	//获取成员变量
	const double& real()const { return re; }
	const double& imag()const { return im; }
	//支持类型转换的构造
	Complex(double r = 0, double i = 0)
		:re(r), im(i)
	{
		std::cout << this << std::endl;
	}
	//拷贝构造
	Complex(const Complex& Com);


	//自我赋值检测的拷贝赋值
	Complex& operator=(const Complex& Com);
	//bool类型转换,在原点为返回false
	explicit operator bool() const noexcept;
	//取反
	Complex operator-() const;
	//前置++,__,实部加1,减法1
	Complex operator++();
	Complex operator--();
	//后置++,__,实部加1,减法1
	Complex operator++(int);					//重点
	Complex operator--(const int);				//const int和int无差别,不能同时存在
	//重载!,求共轭复数
	Complex operator!() const;
	//重载()为仿函数,求模
	double operator()() const;

	//重载<<用以输出复数
	friend std::ostream& operator<<(std::ostream&, const Complex&);
	//加减乘除
	friend Complex operator+(const Complex& Com1, const Complex& Com2);
	friend Complex& operator+=(Complex& Com1, const Complex& Com2);
	friend Complex operator-(const Complex& Com1, const Complex& Com2);
	friend Complex& operator-=(Complex& Com1, const Complex& Com2);
	friend Complex operator*(const Complex& Com1, const Complex& Com2);
	friend Complex& operator*=(Complex& Com1, const Complex& Com2);
	friend Complex operator/(const Complex& Com1, const Complex& Com2);
	friend Complex& operator/=(Complex& Com1, const Complex& Com2);
	//相等、大小判断
	friend bool operator==(const Complex& Com1, const Complex& Com2);
	friend bool operator!=(const Complex& Com1, const Complex& Com2);
	friend bool operator<(const Complex& Com1, const Complex& Com2);
	friend bool operator<=(const Complex& Com1, const Complex& Com2);
	friend bool operator>(const Complex& Com1, const Complex& Com2);
	friend bool operator>=(const Complex& Com1, const Complex& Com2);
};

Complex.cpp

#include "Complex.h"

Complex::Complex(const Complex& Com)
{
	std::cout << this << std::endl;
	this->re = Com.re;
	this->im = Com.im;
}
Complex& Complex::operator=(const Complex& Com)
{
	std::cout << this << std::endl;
	if (this != &Com)
	{
		this->re = Com.re;
		this->im = Com.im;
		return (*this);
	}
	return (*this);
}

Complex::operator bool() const noexcept		//explicit只能写在声明中,不能写在定义中。
{
	if (0 == this->re && 0 == this->im)
		return false;
	else
		return true;
}
Complex Complex::operator-() const
{
	return Complex(-this->re, -this->im);
}
//前置++,--
Complex Complex::operator++()
{
	return Complex(++this->re, this->im);
}
Complex Complex::operator--()
{
	return Complex(--this->re, this->im);
}

//后置++,--
Complex Complex::operator++(int)
//Complex operator++(const int)		//亦可
{
	return Complex(this->re++, this->im);
	//拆分开则为下列三行
	/*Complex Com(*this);
	++this->re;
	return Com;*/
}
Complex Complex::operator--(const int)
{
	return Complex(this->re--, this->im);
}
Complex Complex::operator!() const
{
	return Complex(this->re, -this->im);
}
double Complex::operator()() const
{
	return sqrt(pow(this->re, 2) + pow(this->im, 2));
}

std::ostream& operator<<(std::ostream& os, const Complex& Com)
{
	return os << '(' << Com.real() << ',' << Com.imag() << ')';
}

Complex operator+(const Complex& Com1, const Complex& Com2)
{
	return Complex(Com1.re + Com2.re, Com1.im + Com2.im);
}
Complex& operator+=(Complex& Com1, const Complex& Com2)
{
	Com1.re += Com2.re;
	Com1.im += Com2.im;
	return Com1;
}
Complex operator-(const Complex& Com1, const Complex& Com2)
{
	return Complex(Com1.re - Com2.re, Com1.im - Com2.im);
}
Complex& operator-=(Complex& Com1, const Complex& Com2)
{
	Com1.re -= Com2.re;
	Com1.im -= Com2.im;
	return Com1;
}
Complex operator*(const Complex& Com1, const Complex& Com2)
{
	return Complex((Com1.re * Com2.re) - (Com1.re * Com2.re), (Com1.im * Com2.re) + (Com1.re * Com2.im));
}
Complex& operator*=(Complex& Com1, const Complex& Com2)
{
	Com1.re = (Com1.re * Com2.re) - (Com1.re * Com2.re);
	Com1.im = (Com1.im * Com2.re) + (Com1.re * Com2.im);
	return Com1;
}
Complex operator/(const Complex& Com1, const Complex& Com2)
{
	double acbd = (Com1.re * Com2.re) + (Com1.re * Com2.re);
	double bc_ad = (Com1.im * Com2.re) + (Com1.re * Com2.im);
	double c2d2 = Com2.re * Com2.re + Com2.im * Com2.im;
	return Complex(acbd / c2d2, bc_ad / c2d2);
}
Complex& operator/=(Complex& Com1, const Complex& Com2)
{
	double acbd = (Com1.re * Com2.re) + (Com1.re * Com2.re);
	double bc_ad = (Com1.im * Com2.re) + (Com1.re * Com2.im);
	double c2d2 = Com2.re * Com2.re + Com2.im * Com2.im;
	Com1.re = acbd / c2d2;
	Com1.im = bc_ad / c2d2;
	return Com1;
}

bool operator==(const Complex& Com1, const Complex& Com2)
{
	if (Com1.real() == Com2.real() && Com1.imag() == Com2.imag())
		return true;
	else
		return false;
}
bool operator!=(const Complex& Com1, const Complex& Com2)
{
	if (Com1.real() != Com2.real() || Com1.imag() != Com2.imag())
		return true;
	else
		return false;
}
bool operator<(const Complex& Com1, const Complex& Com2)
{
	if (Com1() < Com2())
		return true;
	else
		return false;

}
bool operator<=(const Complex& Com1, const Complex& Com2)
{
	if (Com1() <= Com2())
		return true;
	else
		return false;
}
bool operator>(const Complex& Com1, const Complex& Com2)
{
	if (Com1() > Com2())
		return true;
	else
		return false;
}
bool operator>=(const Complex& Com1, const Complex& Com2)
{
	if (Com1() >= Com2())
		return true;
	else
		return false;
}

String.h

#pragma once
#include <iostream>
#include <cstring>

class String
{
private:
	char *m_StrData;
public:
	String(const char *strp = nullptr)
	{
		if (nullptr != strp)
		{
			this->m_StrData = new char[strlen(strp) + 1];
			strcpy_s(m_StrData, strlen(strp) + 1, strp);
		}
		else
		{
			this->m_StrData = new char[1];
			*(this->m_StrData) = '\0';
		}
	}
	String(const String& strp)
	{
		this->m_StrData = new char[strp.leng() + 1];
		strcpy_s(this->m_StrData, strp.leng() + 1, strp.m_StrData);
	}
	String& operator= (const String& strp)
	{
		if (this != &strp)
		{
			delete[] m_StrData;
			m_StrData = new char[strp.leng() + 1];
			strcpy_s(this->m_StrData, strp.leng() + 1, strp.m_StrData);
			return (*this);
		}
		return (*this);
	}
	~String()
	{
		if (nullptr != m_StrData)
			delete[] this->m_StrData;
	}

	//字符个数
	unsigned int leng() const
	{
		return strlen(this->m_StrData);
	}

	char& operator[](const unsigned int off)
	{
		return *(m_StrData + off);
	}
	const char& operator[](const unsigned int off) const
	{
		return *(m_StrData + off);
	}
	String* operator->()
	{
		return this;
	}
	const char* operator*() const
	{
		return (this->m_StrData);
	}
	//重载<<
	friend std::ostream& operator<<(std::ostream&, const String&);
};

std::ostream& operator<<(std::ostream& os, const String& strp)
{
	return os << strp.m_StrData;
}

如有错误或不足欢迎评论指出!创作不易,转载请注明出处。如有帮助,记得点赞关注哦(⊙o⊙)
更多内容请关注个人博客:https://blog.csdn.net/qq_43148810

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大胡子的艾娃

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值