运算符重载

一、运算符重载

再讨论运算符重载之前我们先来介绍下函数重载,函数重载就是对一个已有的函数

赋予新的含义,使之实现新功能,因此一个函数名就可以代表不同功能的函数

运算符重载:简单点来说就是赋予 运算符 一个新的功能,新的运算规则

当然了基础数据类型编译器知道运算规则,所以可以直接运算

下面来介绍下运算符重载的步骤:

1、写出函数名 operator + 重要的运算符  (比如+:operator+, *: operator*  []: operator[])

2、根据运算需要的操作数写出 参数列表,加法需要两个操作数,分别写出左和右操作数:operator+(c1, c2);

3、根据需要写出函数返回值:Complex operator+(const Complex &c1, const Complex &c2)

class Complex
{
	friend Complex add (const Complex &c1, const Complex &c2);
	friend Complex operator+(const Complex &c1, const Complex &c2);
	friend Complex operator+(const Complex &c1, int num);
public:
	Complex()
	{
		a = 0;
		b = 0;
	}

	Complex(int a, int b)
	{
		this->a = a;
		this->b = b;
	}

	void print()
	{
		printf ("%d + %di\n", a, b);
	}

	Complex add(const Complex &c2)
	{
		Complex tmp(a+c2.a, b+c2.b);
		return tmp;
	}

	Complex operator-(const Complex &c2) const
	{
		Complex tmp(a-c2.a, b-c2.b);
		return tmp;
	}
private:
	int a;  // 实部
  	int b;  // 虚部
};

Complex add(const Complex &c1, const Complex &c2)
{
	Complex tmp(c1.a+c2.a, c1.b+c2.b);
	return tmp;
}

// 全局函数
// operator+ 可以理解成一个函数名
Complex operator+(const Complex &c1, const Complex &c2)
{
	Complex tmp(c1.a+c2.a, c1.b+c2.b);
	return tmp;
}

Complex operator+(const Complex &c1, int num)
{
	Complex tmp(c1.a + num, c1.b);
	return tmp;
}

int main3_2()
{
	Complex c1(1,2), c2(3,4), c;
	// c = c1 + c2; 

	// 全局使用
	c = operator+(c1, c2);

	// 内部使用
	c = c1.add(c2);

	// 运算符重载 内部 和 全局函数 同时只能存在一个
	// 全局到内部的转换:隐藏左操作数
	c = c1.operator-(c2);
	c = c1 - c2; 
	c.print();
	return 0;
}

二、单目运算符

前置自增运算符

int main4_1()
{
	Complex c(1,2), c2(3,4);


	// 复数自增 实部虚部同时自增
	// operator ++
	// operator ++(c)  ====> operator ++(Complex &c)
	// void operator ++(Complex &c)
	// ++c;
	// c.print();


	Complex c1 = ++c; // Complex c1 = operator ++(c)


	c1 = ++c + c2;  // c1 = ++c + c2;    (operator ++(c)).operator+(c2)
	c1.print();


	// 内部  Complex& operator --(Complex &c)  ===>  Complex& operator --()
	--c1;
	c1.print();


	return 0;
}

后置自增运算符

// 后置++ 有一个占位参数来与 前置++进行区分
// 先使用,再自增
Complex operator++(Complex &c, int)
{
	// 定义一个临时对象来保存 c 的值
	Complex tmp(c.a, c.b);
	c.a++;
	c.b++;

	return tmp;
}
// 后置自增运算符:c++
int main()
{
	Complex c, c1(1,2),c2(3,4);
	// Complex operator++(Complex &c, int)
	c = c1++ + c2;
	c.print();
	c1.print();

	// 内部 :Complex operator--(Complex &c, int)   ====> Complex operator--(int) 
	c1--;
	c1.print();

	return 0;
}

三、左移与右移操作符

 << 是一个操作符  我们可以重载它的功能

 cout  是一个对象 cout 是 ostream 的一个对象

 operator<< (cout, c1)  

 operator<< (ostream &out, const Complex &c);  

左移和右移操作只能用友元函数进行重载,写成全局函数,无法写成内部函数,因为无法修改 ostream 类


四、赋值运算符

Teacher &operator=(const Teacher &obj)
	{
		// 函数入口参数检查  如果是自己直接返回
		if (&obj == this)
			return *this;


		// 1、释放原有的空间
		if (name != NULL)
			delete [] name;


		// 2、开辟新空间
		this->name = new char[20];


		// 复制
		this->age = obj.age;
		strcpy (this->name, obj.name);


		return *this;
	}

默认的赋值运算是一个 浅拷贝 的过程


五、函数调用运算符

class Test
{
public:
	Test(int a)
	{
		this->a = a;
	}

	void operator()(int b1, int b2)	
	{
		printf ("a = %d\n", a);
	}
private:
	int a;
};

int main7_1()
{
	// 定义对象
	Test a(10);
	
	// ()是函数调用运算符
	// operator()(Test &a)  ===>   operator()()
	a(1, 2);  // a 是一个对象, 不是一个函数, 但是它的行为和函数很像, 这样的使用  叫仿函数

    return 0;
}


六、逻辑运算符

逻辑运算符的短路规则:

|| 有一个表达式为真,后面的表达式将不再执行

&& 有一个表达式为假,后面的表达式将不再执行

Test8_1 t1(0), t2(1), t3(2);

bool operator &&(Test8_1 &t1, Test8_1 &t2);  ===> bool operator &&(Test8_1 &t2);
t1.operator&& (t2 = t3)
逻辑运算符重载无法实现短路运算规则
t1 && (t2 = t3);

七、数组下标运算符的重载

[]运算符用于访问数据对象的元素

重载格式类型 类::operator[](类型);

class Array
{
public:
	Array (int len = 0)
	{
		this->len = len;
		p = new int[len];
	}

	int &operator[](int index)
	{
		return p[index];
	}
private:
	int len;
	int *p


int main()
{
	Array a(10);
	for (int i = 0; i < 10; i++)
	{
		// operator[] (Array &a, int i) ==> operator[] ( int i)
		// a.operator[](i) = i;
 		a[i] = i;
	}

    return 0;
}







评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值