运算符重载 :对已有的运算符重新进行定义,赋予其另一种功能,以适应不同的数据类型
1.加号运算符重载
#include <iostream>
#include <string>
using namespace std;
//加号运算符重载
class Person{
public:
int m_A;
int m_B;
//1.成员函数实现+号重载
Person operator+(Person &p){
Person temp;
temp.m_A=this->m_A+p.m_A;
temp.m_B=this->m_B+p.m_B;
return temp;
}
};
//2.全局函数实现+号重载
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 num){
Person temp;
temp.m_A=p1.m_A+num;
temp.m_B-=p1.m_B+num;
return temp;
}
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.operator+(p2);
//全局函数重载本质调用
//Person p3=operator+(p1,p2);
//Person p3=p1+p2;
Person p3=p1+100;//Person + int
//运算符重载 也可以发生函数重载
cout<<p3.m_A<<p3.m_B<<endl;
}
int main(){
test01();
}
总结:对于内置的数据类型表达式的运算符是不可能改变的 不要滥用!
2.左移运算符重载
#include <iostream>
#include <ostream>
#include <string>
using namespace std;
//左移运算符重载
class Person{
friend ostream& operator<<(ostream &cout,Person &p);
private:
int m_A;
int m_B;
public:
Person(int a,int b){
m_A=a;
m_B=b;
}
//通常不会利用成员函数重载<< 无法实现cout在左侧
};
//只能利用全局函数重载左移运算符
//链式编程
ostream& operator<<(ostream &cout,Person &p){
cout<<p.m_A<<p.m_B<<endl;
return cout;
}
void test01(){
Person p(10,10);
cout<<p<<endl;
}
int main(){
test01();
}
3.递增运算符重载
#include <iostream>
#include <string>
#include <ostream>
using namespace std;
class myInteger{
friend ostream& operator<<(ostream &cout,myInteger &myint);
public:
myInteger(){
m_Num=0;
}
//重载前置++运算符 返回引用是为了一直对一个数据进行递增操作
myInteger& operator++(){
m_Num++;
return *this;
}
//后置递增返回值,局部变量被释放,无法引用
//int 代表占位参数,可以用于区分前置和后置递增
myInteger operator++(int){
myInteger temp=*this;
m_Num++;
return temp;
}
private:
int m_Num;
};
ostream& operator<<(ostream &cout,myInteger &myint){
cout<<myint.m_Num<<endl;
return cout;
}
// void test01(){
// myInteger myint;
// cout<<++myint<<endl;
// }
void test02(){
myInteger myint;
cout<<myint++<<endl;
cout<<myint<<endl;
}
int main(){
test02();
}
4.赋值运算符重载
赋值运算符operator=对属性进行值拷贝
如果类中有属性指向堆区,做赋值操作时也会出现深浅拷贝问题
#include <cstddef>
#include <cstdio>
#include <iostream>
#include <string>
#include <ostream>
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.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);
cout<<*p1.m_Age<<endl;
Person p2(20);
p2=p1;//赋值操作
cout<<*p2.m_Age<<endl;
}
int main(){
test01();
}
5.关系运算符重载
#include <iostream>
#include <ostream>
#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;
}
return false;
}
string m_Name;
int m_Age;
};
void test01(){
Person p1("Tom",18);
Person p2("Tom",18);
if (p1==p2) {
cout<<"p1==p2"<<endl;
}
else {
cout<<"p1!=p2"<<endl;
}
}
int main(){
test01();
}
6.函数调用运算符重载 ()
由于重载后使用的方式非常像函数调用,称为仿函数 没有固定写法
#include <cstdarg>
#include <iostream>
#include <ostream>
#include <string>
using namespace std;
class MyAdd{
public:
int operator()(int num1,int num2){
return num1+num2;
}
};
class MyPrint{
public:
//重载函数调用运算符
void operator()(string test){
cout<<test<<endl;
}
};
void test01(){
MyPrint myPrint;
myPrint("hello world!");
}
void test02(){
MyAdd myAdd;
int ret=myAdd(100,100);
cout<<ret<<endl;
//匿名函数对象
cout<<MyAdd()(100,100)<<endl;
}
int main(){
test01();
test02();
}