[C++核心编程](七):类和对象——运算符重载*

时间:2024-03-04 21:52:16

目录

四则运算符重载

左移运算符重载

递增运算符重载

赋值运算符重载

关系运算符重载

函数调用运算符重载


对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型

四则运算符重载

        对自定义数据类型实现四则运算(加减乘除)操作,比如:自己写成员函数,实现两个对象相加属性后返回新的对象

        注意:四则运算符重载也可以进行函数重载。

        总结:

        1.对于内置的数据类型的表达式的的运算符是不可以改变的

        2.不要滥用运算符重载

#include <iostream>

using namespace std;

class Person
{
public:
	int m_a;
	int m_b;

	Person(int a, int b) :m_a(a), m_b(b)
	{

	}
	//成员函数重载
	Person operator+(const Person &p)
	{
		Person rp(0, 0);
		rp.m_a = this->m_a + p.m_a;
		rp.m_b = this->m_b + p.m_b;
		return rp;
	}
};
//全局函数重载
static Person operator-(const Person& p1, const Person& p2)
{
	Person rp(0, 0);
	rp.m_a = p1.m_a - p2.m_a;
	rp.m_b = p1.m_b - p2.m_b;
	return rp;
}
//函数重载
static Person operator-(const Person& p1, const int value)
{
	Person rp(0, 0);
	rp.m_a = p1.m_a - value;
	rp.m_b = p1.m_b - value;
	return rp;
}

int main(void)
{
	Person p1(10, 10);
	Person p2(10, 10);
	Person p3(5, 5);
	
	Person p4 = p1 + p2; //Person p4 = p1.operator+(p2);
	cout << "p4 m_a value:" << p4.m_a << endl;
	cout << "p4 m_b value:" << p4.m_b << endl;

	Person p5 = p4 - p3; //Person p5 = operator-(p4,p3)
	cout << "p5 m_a value:" << p5.m_a << endl;
	cout << "p5 m_b value:" << p5.m_b << endl;

	Person p6 = p5 - 5; //Person p6 = operator-(p5,5)
	cout << "p6 m_a value:" << p6.m_a << endl;
	cout << "p6 m_b value:" << p6.m_b << endl;
	system("pause");

	return 0;
}

左移运算符重载

        输出自定义的数据类型,比如:直接输出一个对象就可以输出其成员属性

        总结:左移运算符配合友元可以实现输出自定义数据类型

#include <iostream>
#include <string>

using namespace std;

class Person
{
	friend static ostream& operator<<(ostream& cout, Person& p);
public:
	Person(int a, int b)
	{
		m_a = a;
		m_b = b;
	}
private:
	//通常不使用 成员函数重载 左移运算符 ,无法实现cout在左侧
	int m_a;
	int m_b;
};

static ostream& operator<<(ostream &cout, Person& p) // operator<<(cout, p)
{
	cout << "m_a=" << p.m_a << endl;
	cout << "m_b=" << p.m_b << endl;
	return cout;
}

static void test(void)
{
	Person p(10, 10);

	cout << p << endl;
}

int main(void)
{
	test();
	system("pause");
	return 0;
}

递增运算符重载

        区分前置和后置的差别!!

#include <iostream>
#include <string>

using namespace std;

class MyInteger
{
	friend static ostream& operator<<(ostream& cout, MyInteger p);
public:
	MyInteger(int b)
	{
		m_b = b;
	}
	//重载 后置,int 占位参数 int ,区分前置和后置
	MyInteger operator++(int)
	{
		MyInteger temp = *this;
		++*this;
		return temp;
	}
	//重载 前置
	MyInteger& operator++() //返回引用是为了一直对一个数据进行操作
	{
		++m_b;
		return *this;
	}
private:
	int m_b;
};

static ostream& operator<<(ostream& cout, MyInteger p) // operator<<(cout, p)
{
	cout << p.m_b;
	return cout;
}

static void test(void)
{
	MyInteger p(0);

	cout << ++p << endl;
	cout << p << endl;
}

static void test1(void)
{
	MyInteger p1(0);

	cout << p1++ << endl;
	cout << p1 << endl;
}

int main(void)
{
	test();
	test1();
	system("pause");
	return 0;
}

赋值运算符重载

         c++至少给一个类添加4个函数:前三个略

        4.赋值运算符operator=,对属性进行值拷贝(注意深浅拷贝问题)

#include <iostream>
#include <string>

using namespace std;

class Person
{
public:
	Person(int b)
	{
		m_age = new int(b);
	}
	~Person()
	{
		if (m_age != NULL)
		{
			delete m_age;
			m_age = NULL;
		}
	}
	Person& operator=(const Person & p) //重载赋值运算符,使用深拷贝
	{
		if (m_age != NULL)
		{
			delete m_age;
			m_age = NULL;
		}
		m_age = new int(*p.m_age);
		return *this;
	}

	int *m_age;
};

static void test1(void)
{
	Person p1(12);
	Person p2(19);
	Person p3(14);
	p3 = p2 = p1;

	cout << "p1年龄为:" << *p1.m_age << endl;
	cout << "p2年龄为:" << *p2.m_age << endl;
	cout << "p3年龄为:" << *p3.m_age << endl;
}

int main(void)
{
	test1();
	system("pause");
	return 0;
}

关系运算符重载

        重载关系运算符,让两个自定义的数据类型进行对比操作

#include <iostream>
#include <string>

using namespace std;

class Person
{
public:
	Person(string name, int age)
	{
		m_name = name;
		m_Age = age;
	}
	
	bool operator==(Person& p)
	{
		if (this->m_name == p.m_name && this->m_Age == p.m_Age)
		{
			return true;
		}
		else 
		{
			return false;
		}
	}

	string m_name;
	int m_Age;
};

static void test1(void)
{
	Person p1("Tom", 19);
	Person p2("Mac", 19);

	if (p1 == p2)
	{
		cout << "p1 == p2" << endl;
	}
	else
	{
		cout << "p1 != p2" << endl;
	}

}

int main(void)
{
	test1();
	system("pause");
	return 0;
}

函数调用运算符重载

  • 函数调用运算符() 也可以重载
  • 由于重载后使用的方式非常像函数的调用,故称仿函数
  • 仿函数没有固定写法,非常灵活(返回值、参数均不固定)
#include <iostream>
#include <string>

using namespace std;

class Myprint
{
public:
	void operator()(string test)
	{
		cout << test << endl;
	}
};

class MyAdd
{
public:
	int operator()(int a, int b)
	{
		return a + b;
	}
};

static void test1(void)
{
	Myprint myprint;

	myprint("Hello World!");//仿函数

	MyAdd myadd;
	int result = myadd(1, 1);
	cout << "result = " << result << endl;

	//匿名函数对象
	cout << "result = " << MyAdd()(11, 11) << endl;
}

int main(void)
{
	test1();
	system("pause");
	return 0;
}

推荐:[C++核心编程](五):类和对象——友元(friend)