目录
一、运算符重载基础
c++运算符重载是赋予运算符具有操作对象的功能
对于c++运算符重载的本质就是函数调用,所以运算符重载函数如何编写最>为重要
函数返回值当前运算符运算介绍后产物类型,int a,int b,a+b返回int类型
函数名:operator和运算符组成函数名
函数参数
运算符重载函数是类中成员函数:函数参数等于操作数-1
运算符重载函数是友元函数:函数参数等于操作数
**函数体:**写运算符的实际想要的运算
c++类中存在一个赋值的重载函数(默认)
#include <iostream>
using namespace std;
class MM
{
public:
MM(int i,int j):i(i),j(j){}
void print()
{
cout<<this->i<<"\t"<<this->j<<endl;
}
MM operator+(MM& mm)
{
return MM(this->i+mm.i,this->j+mm.j);
}
friend void operator+=(MM&mm1,MM&mm2) //要修改数据,传入引用
{
mm1.i+=mm2.i;
mm1.j+=mm2.j;
}
protected:
int i;
int j;
};
int main(int argc, char** argv)
{
MM mm1(1,2);
MM mm2(5,8);
MM mm3=mm1+mm2;
mm3.print();
MM mm4=mm1.operator+(mm2); //显示调用
mm4.print();
//友元重载
mm1+=mm2;
mm1.print();
operator+=(mm3,mm2); //显示调用
mm3.print();
}
二、c++特殊运算符重载
1. .= () -> [] 只能重载为类成员函数
2. 运算符重载必须存在至少一个自定义类型才能重载
3. . .* ?: :: 不能被重载
4. c++只允许重载已有运算符,不能无中生有
5. 习惯行为:单目运算符采用类的成员函数重载,双目运算符采用友元重载
1.++和–运算符的重载
- 对于++和–重载,通过增加无用参数(int)标识为后置运算
#include<iostream>
#include<string>
using namespace std;
class MM
{
public:
MM(string name="",int money=0):name(name),money(money){}
MM operator++() //前置
{
this->money++;
return *this;
}
MM operator++(int) //后置
{
return MM(this->name,this->money++);
}
void print()
{
cout<<this->money<<"\t"<<this->name<<endl;
}
protected:
string name;
int money;
};
int main()
{
MM mm1("king",100);
MM mm2=mm1++;
mm2.print();
MM mm3=++mm2;
mm3.print();
}
2.c++流对象重载
- cout本质是一个类的对象:
ostream
,cin本质也是一个类的对象:istream
- 流重载必须要用友元方式重载
- 流重载尽量使用引用类型———————————————
#include<iostream>
#include<string>
using namespace std;
class MM
{
public:
MM(string name="",int money=0):name(name),money(money){}
void print()
{
cout<<this->money<<"\t"<<this->name<<endl;
}
friend ostream& operator<<(ostream& out,MM& object);
friend istream& operator>>(istream& in,MM& object);
protected:
string name;
int money;
};
ostream& operator<<(ostream& out,MM& object)
{
out<<object.name<<"\t"<<object.money<<endl;
return out;
}
istream& operator>>(istream& in,MM& object)
{
cout<<"请输入info:"<<endl;
in>>object.name>>object.money;
return in;
}
int main()
{
MM mm1("king",100);
cin>>mm1;
cout<<mm1<<endl;
}
3.c++文本重载
- 所谓文本重载,就是重载后缀,固定写法
- 函数参数:
unsigned long long
(一定是)- 函数名:
operator""
要重载的后缀——>一般重载后缀采用下划线系列- 一个运算符或者一个后缀只能重载被重载一次
#include<iostream>
#include<string>
using namespace std;
unsigned long long operator"" _h(unsigned long long num)
{
return num*3600;
}
unsigned long long operator"" _min(unsigned long long num)
{
return num*60;
}
unsigned long long operator"" _s(unsigned long long num)
{
return num;
}
int main()
{
cout<<1_h+3_min+2_s<<endl;
return 0;
}
4.c++operator实现隐式转换
- 所谓隐式转换就是可以让对象直接赋值给普通对象
- 模板
- operator 隐式转换的类型()
{
return 数据;
}
#include<iostream>
#include<string>
using namespace std;
class MM
{
public:
MM(string name="",int money=0):name(name),money(money){}
void print()
{
cout<<this->money<<"\t"<<this->name<<endl;
}
//隐式转换----->便捷获取数据成员的接口
operator int()
{
return this->money;
}
operator string()
{
return this->name;
}
protected:
string name;
int money;
};
int main()
{
MM mm("king",89);
int money=mm;
string name=mm;
cout<<money<<"\t"<<name<<endl;
}
三、运算符的应用场景
1.迭代器实现
- 让对象模拟指针的行为
- 模板
- #include<iostream>
#include<string>
using namespace std;
int main()
{
string king="King word!";
string::iterator iter;
for(iter=king.begin();iter!=king.end();iter++)
{
cout<<*iter<<" ";
}
cout<<endl;
}
#include<iostream>
#include<string>
using namespace std;
struct Node
{
int data;
Node* next;
Node(int data=0):data(data),next(nullptr){}
};
class List
{
public:
void push_front(int data)
{
Node* newNode=new Node(data);
if(curSize==0)
tailNode=newNode;
else
newNode->next=frontNode;
frontNode=newNode;
curSize++;
}
class iterator
{
public:
iterator(Node* pmove=nullptr):pmove(pmove){}
iterator operator++(int)
{
return iterator(pmove=pmove->next);
}
bool operator!=(iterator&& object) const
{
return this->pmove!=object.pmove;
}
int operator*()
{
return pmove->data;
}
protected:
Node* pmove;
};
protected:
Node* frontNode=nullptr;
Node* tailNode=nullptr;
int curSize=0;
public:
iterator begin()
{
return iterator(frontNode);
}
iterator end()
{
return iterator(nullptr);
}
};
int main()
{
List list;
for(int i=0;i<=10;i++)
{
list.push_front(i+1);
}
List::iterator iter;
for(iter=list.begin();iter!=list.end();iter++)
{
cout<<*iter<<" ";
}
return 0;
}
2.函数包装器
- 把函数指针包装成一个对象
#include<iostream>
#include<string>
using namespace std;
class Func
{
using Fun=void(*)();
public:
Func(Fun pf):pf(pf){}
void operator()()
{
pf();
}
protected:
Fun pf;
};
void print()
{
cout<<"我是函数包装器"<<endl;
}
int main()
{
Func x(print);
x(); //通过对象调用函数
return 0;
}
3.智能指针
- 可以实现内存的自动申请与释放
- #include<iostream>
#include<string>
using namespace std;
class King
{
public:
King(int* ptr):ptr(ptr){}
~King()
{
if(ptr!=nullptr)
{
delete ptr;
ptr=nullptr;
}
}
int* operator->()
{
return this->ptr;
}
int operator*()
{
return *this->ptr;
}
protected:
int *ptr;
};
int main()
{
King k(new int(9999));
cout<<*k<<endl; //通过对象访问数据
return 0;
}
- 版权声明:本文为CSDN博主「热爱编程的小K」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/qq_72157449/article/details/128664136