一.加法运算符重载
- 实现两个自定义类型的数据的加法
- 可以实现person+person
- 也可以实现person+int(函数重载)
#include<iostream>
using namespace std;
#include<string>
class person
{
public:
成员函数的重载
/*person operator+(person p)
{
person temp;
temp.m_A=this->m_A+p.m_B;
temp.m_B=this->m_A+p.m_B;
return temp;
}*/
int m_A;
int m_B;
};
全局函数的重载
person operator+(person &p1, person &p2)
{
person temp;
temp.m_A= p1.m_A + p2.m_A;
temp.m_B = p1.m_B + p2.m_B;
return temp;
}
//函数重载的版本,函数名一样,但是传的参数不一样
person operator+(person& p1, int a)
{
person temp;
temp.m_A = p1.m_A + a;
return temp;
}
void test01()
{
person p1;
p1.m_A = 10;
p1.m_B = 20;
person p2;
p2.m_A = 10;
p2.m_B = 20;
//成员函数重载本质调用
//person p3 = p1.operator+(p2);
//全局函数重载本质调用
//person p3 = operator+(p1, p2);
person p3=p1+p2;
//运算符重载 也可以发生函数重载
person p4 = p1 + 10;
cout << "p3.m_A=" << p3.m_A << endl;
cout << "p3.m_B=" << p3.m_B << endl;
cout << "函数重载p4.m_A=" << p4.m_A << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
二.左移运算符
- 利用运算符重载将不同的
- 然后因为成员函数最后形成的格式是p<<cout,不符合我们想要的结果;所以只能用全局函数进行重载;
- 然后假设左移运算符输出的值是类内的私有化成员,则需要用到前边学到的友元,使其能访问。
#include<iostream>
using namespace std;
#include<string>
class person
{
friend void operator<<(ostream& cout, person& p);
public:
person(int a, int b)
{
m_A = a;
m_B = b;
}
private:
利用成员函数来重载 左移运算符 p.operator<<(cout) 简化版本p<<cout
// 因为简化后的形式不是我们想要的,所以一般不用成员函数去写左移重载
//void operator<<(cout)
//{
//}
int m_A;
int m_B;
};
//用全局函数重载作为左运算符
//cout 属于标准的输出流对象ostream
//本质operator<<(cout ,p)可简化为cout <<p
void operator<<(ostream &cout,person &p)//这样写返回的不是cout,在cout后不能加endl
//更改:ostream &void operator <<(ostream &cout,person &p) 这样返回值就是输出流了
{
cout << "m_A:" << p.m_A << "m_B:" << p.m_B;
}
void test01()
{
person p1(10,20);
/*p1.m_A = 10; 因为m_A,m_B被私有化了,所以要创建一个构造函数,对接类内的函数与类外的函数数
p1.m_B = 20;*/
cout << p1;
person p2(10,20);
/*p2.m_A = 10;
p2.m_B = 20;*/
cout << p2;
}
int main()
{
test01();
system("pause");
return 0;
}
三.递增运算符重载
-
前置和后置重载的区分
- 是否有占位参数int
前置 operator++()
后置 operator++(int)
- 返回的值
前置 返回的是引用 person& operator()
后置 返回的是值 person operator(int)
2.代码
#include<iostream>
using namespace std;
#include<string>
class person
{
friend ostream& operator<<(ostream& cout, person p);
public:
//前置++ 返回引用是为了一直对一个数据进行递增操作
person operator++()
{
m_A++;
return *this;
}
//后置++ 返回的是值
//int 代表的是占位参数,可以区分前置和后置
person operator++(int)
{
//先 记录当时的结果
person temp = *this;
//后 递增
m_A++;
//最后将记录结果返回
return temp;
}
private :
int m_A=0;
};
ostream& operator<<(ostream& out, person p) //把ostream自身(引用)作为一个返回
{
out << p.m_A;
return out;
}
void test01()
{
person p1;
cout << ++(++p1)<<endl;
}
int main()
{
test01();
system("pause");
return 0;
}
四.赋值运算符重载
C++编译器至少给一个类添加4个函数
- 默认构造函数(无参 函数体为空)
- 默认析构函数(无参 函数体为空)
- 默认拷贝构造函数,对属性进行值拷贝
- 赋值运算符 operator= 对属性进行值拷贝
如果类中有属性指向堆区,对属性进行值拷贝
#include<iostream>
using namespace std;
class person
{
public:
person(int age)
{
m_age = new int(age);
}
~person()
{
if (m_age != NULL)
{
delete m_age;
m_age = NULL;
}
//重载 赋值运算符
}
person& operator=(person &p)//返回引用
{
//编译器提供的浅拷贝
//m_age = p.mage;
//应该先判断是否有属性在堆区,如果有,应该先释放干净,在深拷贝
if (m_age != NULL)
{
delete m_age;
m_age = NULL;
}
m_age = new int(*p.m_age);
return *this;
}
int *m_age=0;
int m_B;
};
void test01()
{
person p1(18);
person p2(20);
person p3(30);
p3=p2 = p1;
cout << "p1的年龄" <<*p1.m_age << endl;
cout << "p2的年龄" << *p2.m_age << endl;
cout << "p3的年龄" << *p3.m_age << endl;
}
int main()
{
test01();
system("pause");
return 0;
}
五.关系运算符重载
自定义类型的对比
#include<iostream>
#include<string.h>
using namespace std;
class person
{
public:
person(int age,string name)
{
m_age = age;
m_name = name;
}
//重载==号
bool operator==(person& p)
{
if (this->m_name == p.m_name && this->m_age == p.m_age)
{
return true;
}
return false;
}
//重载!=
bool operator!=(person& p)
{
if (this->m_name == p.m_name && this->m_age == p.m_age)
{
return false;
}
return true;
}
int m_age;
string m_name;
};
//重载<<
ostream& operator<<(ostream& cout, person p)
{
cout << p.m_age << endl;
cout << p.m_name << endl;
return cout;
}
void test01()
{
person p1(18,"Tam");
person p2(18, "Tam");
if (p1 == p2)
{
cout << "p1和p2是相等的" << endl;
}
else
{
cout << "p1和p2是不相等的" << endl;
}
}
int main()
{
test01();
system("pause");
return 0;
}
六.函数调用运算符重载
- 函数调用运算符{} 也可以发生重载
- 由于重载后使用的方式非常像函数的调用,因此称为仿函数
- 仿函数没有固定的写法,非常灵活
#include<iostream>
#include<string.h>
using namespace std;
class Myapoint
{
void operator()(string test)
{
cout << test << endl;
}
};
//返回空,就只输出字符串
void test01()
{
Myapoint p1;
p1("hello world!");//和函数的调用非常像,所以叫做仿函数
}
class Myadd
{
public:
int operator()(int num1, int num2)
{
return num1 + num2;
}
};
//返回数字,执行加法运算
void test02()
{
Myadd P2;
int ret=P2(10, 20);
cout<<"ret=" << ret << endl;
}
int main()
{
test01();
system("pause");
return 0;
}