复习:
运算符重载:
编译器把运算符当作函数
全局
函数名:operator 运算符
参数表:所有操作数
返回类型:合乎情理即可
成员
函数名:operator 运算符
参数表:除第一个之外的操作数,当前对象作为第一个操作数
返回类型:合乎情理即可
编译器会尝试这两种形式([]()=->type只当成员函数),如果两种都有或者都没有,编译失败。每个运算符函数只允许有其中一种形式。
operator type()不写返回类型却胜写返回类型,因为函数名里面已经包含返回类型
ostream& operator<<(ostream& o,const A& x);
istream& operator>>(istream& i,A& x);
这两个只能写成非成员函数。如果需要访问对象的私有成员,就要在类里把他们声明成友元
const对象只能调用const成员函数(const在参数表后)
const成员函数里的this是const A* const,而普通成员函数的this是A* const
const对象中的mutable修饰的数据成员允许修改
双目运算符重载:
a+b: a.operator+(b) operator+(a,b)
单目运算符重载:
&a: a.operator& (),operator&(a)
指针
const int* p;//p指向const int
int const* p;//p指向const int
int* const p;//p本身是const
const int* const p;//p本身是const而且指向const int
运算符重载
->返回内部某个结构变量的地址,编译器通过这个地址执行真正的->操作访问里面的成员
#includeusing namespace std;struct POINT{ int x; int y;};class Pos{ POINT p;public: Pos(int x=0,int y=0){p.x = x,p.y=y;} void move(int cx,int cy){p.x+=cx,p.y+=cy;} void moveto(int x,int y){p.x = x,p.y=y;} POINT* operator->(){ return &p;}};int main(){ Pos a(20,80); cout< x<<","< y< x<<","< y<
new/delete重载负责内存的分配和释放,编译器会在内存分配之后调用构造函数,内存释放之前调用析构函数,有[]和没有[]是不同的运算符
#include#include using namespace std;class A{ int data;public: A(int d=0):data(d){cout<<"A("< <<")"<
++/--
前++前--,正常的单目运算符用法,计算结果就是变量的最新值因此可以直接拿这个对象做计算结果
成员:A& operator++(){... return *this;}
友元:friend A& operator++(A& x){... return x;}
后++后--,非正常用法,计算结果是对象的旧值,必须用临时空间来保存,不能拿对象本身作为计算记过,定义运算符函数时需要一个多余的int哑元。
成员:A operator++(int){... return old;}
友元:friend A operator++(A x,int){... return old;}
运算符重载一定要合乎情理。运算符重载是自己规定运算符对于特定类型的操作数应该如何工作,对于基本类型的运算不应该重载,不应该创造新的运算符,不应该改变操作数的个数。
有些运算符不允许重载:. , .* , ?:,::,typeid,sizeof
#includeusing namespace std;class R{ //分数类 int n; int d;public: friend ostream&operator<<(ostream&o,const R&x){ return o< <<"/"<
#includeusing namespace std;class R{ int n; int d;public:R(int n=0,int d=1):n(n),d(d){} friend ostream& operator<<(ostream&,const R&); R operator++(int){ //返回类型不应该加引用 //虚假的形参 int 用于与前++区分,是哑元 R old = *this; n+=d; return old; }};ostream& operator<<(ostream& o, const R& x){ return o< <<"/"<