运算符重载
运算符作用
对已有的运算符重新进行定义,赋予其另一种功能,以适应不容的数据类型
运算符重载需要注意
- 对于内置的数据类型的表达式的运算符是不可能改变的
- 不要滥用运算符重载
重载’+'运算符
方法
- 成员函数重载’+'
//成员函数实现 + 号运算符重载
Person operator+(const Person& p) {
Person temp;
temp.m_A = this->m_A + p.m_A;
temp.m_B = this->m_B + p.m_B;
return temp;
}
实现
//成员函数重载本质调用
Person p3 = p1.operator+(p2);
//简化调用
Person p3 = p1+p2;
- 全局函数重载’+'
//全局函数实现+号运算符重载
Person operator+(const Person& p1, const Person& p2) {
Person temp(0, 0);
temp.m_A = p1.m_A + p2.m_A;
temp.m_B = p1.m_B + p2.m_B;
return temp;
}
实现
//全局函数重载本质调用
Person p3 = operator+(p1,p2);
//简化调用
Person p3 = p1+p2;
运算符重载也可以发生函数重载
//全局函数实现+号运算符重载
Person operator+(const Person& p2, int val)
{
Person temp;
temp.m_A = p2.m_A + val;
temp.m_B = p2.m_B + val;
return temp;
}
实现
Person p3 = p1 + 100;
<<左移运算符重载
- 重载<<左移运算符配合友元可以实现输出自定义的数据类型
- 成员函数不可以用来重载左移<<运算符,因为无法实现cout在左侧
示例代码
#include <iostream>
#include <string>
using namespace std;
class Person {
friend Person operator + (const Person& p1, const Person& p2);
friend ostream & operator << (ostream & cout, const Person& p);
public:
Person() {}
Person(string name,int age,int tech) {
this->m_Name = name;
this->m_Age = age;
this->m_Techology = tech;
}
void Print() {
cout << "Name:" << this->m_Name << endl;
cout << "Age:" << this->m_Age << endl;
cout << "Techology:" << this->m_Techology << endl;
}
private:
string m_Name;
int m_Age;
int m_Techology;
};
Person operator + (const Person& p1, const Person& p2) {
Person tmp;
tmp.m_Name = "baby";
tmp.m_Age = p1.m_Age + p2.m_Age;
tmp.m_Techology = p1.m_Techology + p2.m_Techology;
return tmp;
}
ostream & operator << (ostream& cout, const Person &p) {
cout << "Name:" << p.m_Name << endl;
cout << "Age:" << p.m_Age << endl;
cout << "Techology:" << p.m_Techology << endl;
return cout;
}
int main()
{
Person p1("ZXW", 18, 100);
Person p2 = Person("HHK",21,100);
Person p3 = p1 + p2;
p1.Print();
p2.Print();
p3.Print();
cout << endl;
cout << p1 << p2 << p3;
return 0;
}
输出
Name:ZXW
Age:18
Techology:100
Name:HHK
Age:21
Techology:100
Name:baby
Age:39
Techology:200
Name:ZXW
Age:18
Techology:100
Name:HHK
Age:21
Techology:100
Name:baby
Age:39
Techology:200
++递增运算符重载
作用:通过重载递增运算符,实现自己的整形数据
重载前置++运算符
//前置++递增运算符
Myint& operator++() {
this->m_Value++;
return *this;
}
返回的一定是引用,因为++(++x)可以叠加,体现了链式编程思想
重载后置++运算符
//后置++递增运算符
Myint operator++(int) {
Myint tmp = *this;
this->m_Value++;
return tmp;
}
返回的一定是值,因为(x++)++语法是错误的,没有采用链式编程思想
示例代码
#include <iostream>
using namespace std;
class Myint {
friend ostream& operator<<(ostream& out, const Myint& myint);
public:
Myint() {}
Myint(int x) {
this->m_Value = x;
}
//前置++递增运算符
Myint& operator++() {
this->m_Value++;
return *this;
}
//后置++递增运算符
Myint operator++(int) {
Myint tmp = *this;
this->m_Value++;
return tmp;
}
private:
int m_Value;
};
ostream& operator<<(ostream& out, const Myint& myint) {
cout << myint.m_Value << endl;
return cout;
}
int main()
{
Myint myint1(10);
cout << ++(++myint1) << endl;
cout << myint1++ << endl;
cout << myint1 << endl;
return 0;
}
输出
12
12
13
=运算符重载
C++编译器至少给一个类添加4个函数
- 默认构造函数(无参,函数体为空)
- 默认析构函数(无参,函数体为空)
- 默认拷贝构造函数,对属性值进行值拷贝
- 赋值运算符operator=,属性进行值拷贝(编译器提供的是浅拷贝)
如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题
(浅拷贝会引发堆区内存重复释放,程序进而崩溃,需要用深拷贝来解决)
关系运算符重载
作用:重载关系运算符,可以让两个自定义类型对你选哪个进行对比操作
bool operator==(const Person& p) {
if (this->m_Name == p.m_Name && this->m_Age == p.m_Age)
return true;
else
return false;
}
函数调用运算符
- 函数调用运算符重载后的使用方式非常像函数的调用,所以称为仿函数
- 仿函数没有固定的写法,非常灵活
- STL库中用到了大量的仿函数
示例程序
class{
int operator()(int x,int y){
return x+y;
}
}
main(){
类名 add;
cout<<add(100,100)<<endl;
}
输出
200
匿名函数对象
cout<<add()(100,100)<<endl;
add()是一个匿名对象
add()(100,100)是一个匿名函数对象
输出
200