C++:类与对象4

C++:类与对象4,第1张

C++:类与对象4 运算符重载

即:对已有的运算符(加减乘除等号)重新定义,赋予另一种功能,以适应不同的数据类型

形式为:operator *** 作符

1、加号运算符 - 实现两个自定义类型的相加 - operator+

重载有两种方式,在类中通过成员函数进行重载;利用全局函数重载

利用成员函数重载时,代码如下:

class Person
{
public:
	Person operator+(Person& p)//通过 成员函数 进行函数重载
		//此处函数名用operator+,下面就可以直接用+
	{
		Person tmp;
		tmp.m_A = this->m_A + p.m_A;
		tmp.m_B = this->m_B + p.m_B;
		//this指向当前对象,通过它可以访问当前对象的所有成员
		return tmp;
	}
public:
	int m_A;
	int m_B;
};

利用全局函数进行重载时,以引用的方式传入对象p1和p2  

Person operator+(Person &p1,Person &p2)//通过 全局函数 进行函数重载
{
	Person tmp;
	tmp.m_A = p1.m_A + p2.m_A;
	tmp.m_B = p1.m_B + p2.m_B;
	return tmp;
}

利用全局函数进行重载时,以引用的方式传入对象p1和整型num   

Person operator+(Person& p1, int num)// 全局函数 函数重载-参数类型变化  //Person + int 型
{
	Person tmp;
	tmp.m_A = p1.m_A + num;
	tmp.m_B = p1.m_B + num;
	return tmp;
}

在测试函数中,创建两个对象p1和p2,分别采用成员函数和全局函数实现两个对象的+运算,可直接使用“+”,实现加号运算符重载; 

void test01()
{
	Person p1;
	p1.m_A = 10;
	p1.m_B = 10;
	Person p2;
	p2.m_A = 10;
	p2.m_B = 10;
	Person p3 = p1 + p2;
	Person p4 = p1 + 10;//Person + int 型
	cout << "p3 m_A=" << p3.m_A << endl;
	cout << "p3 m_B=" << p3.m_B << endl;
}

2、左移运算符 -  operator<<

    不能利用成员函数重载左移运算符,<<函数重载只能用全局函数,全局函数使用友元获得类内访问权限。
   void operator<<(Person &p)
    写成员函数的话,必须在一个对象内来写成员函数,会写成p.operator<<(cout),简化成p<

左移运算符 << 重载

class Person
{
	friend ostream& operator<<(ostream& cout, Person& p);
public:
	Person(int a, int b)
	{
		m_A = a;
		m_B = b;
	}
private:
	int m_A;
	int m_B;
};
ostream & operator<<(ostream &cout,Person &p)//本质 operator<<(cout,p),简化cout<


3、递增运算符 - operator++

递增运算符++重载
自定义整型类
class MyInteger
{
	friend ostream& operator<<(ostream& cout,const MyInteger myint);
public:
	MyInteger()
	{
		m_Num = 0;
	}
	//重载++运算符
	//前置++  先++再使用
	MyInteger& operator++()
	{
		m_Num++;
		return *this;
	}
	//后置++  先使用再++
	MyInteger operator++(int)//int作为占位参数,可以用于区分前置和后置++,与上段代码区别
	{
		//先记录当时结果,再递增,再返回记录的结果
		MyInteger temp = *this;//记录this指针指向的当前值
		m_Num++;
		return temp;
	}
private:
	int m_Num;
};
//重载<<运算符
ostream & operator<<(ostream &cout,const MyInteger myint)
//本质 operator<<(cout,myint),简化cout< 
void test01()
{
	MyInteger myint;
	cout << ++(++myint) << endl;//2
	cout << myint << endl;//重载函数返回类型为引用时,才会对一个数据进行反复操作,才会为2,不然返回新数据,++为1
}
void test02()
{
	MyInteger myint;
	cout << (myint++)++ << endl;
	cout << myint << endl;
}
int main()
{
	test01();
	test02();
	system("pause");
	return 0;
}

4、赋值运算符 - operator=

赋值运算符重载

class Person
{
public:
	Person(int age)
	{
		m_Age = new int(age);//开辟到堆区 手动开辟手动释放
	}
	~Person()
	{
		if (m_Age != NULL)
			m_Age = NULL;
	}
	//重载赋值 *** 作
	Person& operator=(Person& p)
	{
		//浅拷贝:仅仅是指向被复制的内存地址,如果原地址发生改变,那么浅复制出来的对象也会相应的改变。
        //深拷贝:在计算机中开辟一块新的内存地址用于存放复制的对象。
		
		//编译器是提供浅拷贝 - 拷贝的只是地址
		//m_Age=p.m_Age;

		//应该先判断是否由属性在堆区,如果有先释放干净,然后再深拷贝
		if (m_Age != NULL)
		{
			delete m_Age;
			m_Age = NULL;
		}
		//深拷贝
		m_Age = new int(*p.m_Age);
		//返回对象本身
		return *this;
	}
	int *m_Age;
};
void test01()
{
	Person p1(18);
	Person p2(20);
	Person p3(30);

	p2 = p1;//赋值 *** 作
	p1 = p2 = p3;
    //err,返回类型改为Person &后可以 *** 作

	cout << "p1年龄" << *p1.m_Age << endl;
	cout << "p2年龄" << *p2.m_Age << endl;
	cout << "p3年龄" << *p3.m_Age << endl;
}
int main()
{
	test01();

	int a = 0;
	int b = 10;
	int c = 20;
	a = b = c;//是正确的

	system("pause");
	return 0;
}

 


5、关系运算符 - operator==

关系运算符重载 - 对比两个自定义类型
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;
	}
	bool operator!=(Person& p) //不等 运算符重载
	{ 
		if (this->m_Name == p.m_Name && this->m_Age == p.m_Age)
			return false;
		else
			return true;
	}
	string m_Name;
	int m_Age;
};
void test01()
{
	Person p1("Tom", 18);
	Person p2("Tm", 18);
	if (p1 == p2)
	{
		cout << "1相等" << endl;
	}
	else
	{
		cout << "1不等" << endl;
	}
	if (p1 != p2)
	{
		cout << "2不等" << endl;
	}
	else
	{
		cout << "2相等" << endl;
	}
}
int main()
{
	test01();
	system("pause");
	return 0;
}

 


6、调用运算符 - operator()

//重载函数调用运算符()
//仿函数
class MyPrint
{
public:
	void operator()(string test)
	{
		cout << test << endl;
	}
};
class MyAdd
{
public:
	int operator()(int num1, int num2)
	{
		return num1 + num2;
	}
};
void test01()
{
	MyPrint myPrint;
	myPrint("hello");
}
void test02()
{
	MyAdd myAdd;
	int num=myAdd(10,20);
	cout << num << endl;

	//匿名函数对象
	cout << MyAdd()(10, 20) << endl;
}

int main()
{
	test01();
	test02();
	system("pause");
	return 0;
}

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5636344.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-16
下一篇 2022-12-16

发表评论

登录后才能评论

评论列表(0条)

保存