运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,使他适应不同的数据类型。
运算符重载的本质:函数重载 关键字:operator
一元运算符就是对一个数进行操作
一元运算符重载利用成员函数进行重载时,就不用给()内传参数了,()内有隐藏的*this
定义一个Coordinate坐标类,分别通过成员函数和友元函数对负号运算符进行重载
通过成员函数对负号运算符进行重载:
#include<iostream> using namespace std; /****************************************** 一元运算符重载 要求: 定义一个Coordinate坐标类 成员函数:构造、getX、getY,数据成员:m_iX,m_iY 1、负号运算符重载(成员函数,友元函数) 2、++运算符重载(前置++,后置++) *******************************************/ class Coordinate { Coordinate(int x,int y); //通过成员函数对符号运算符进行重载 Coordinate &operator-();//让他返回出来的是它本身,这样才能让他再进行负号运算符的运算,所以返回值写成Coordinate & int getX(); int getY(); private: int m_iX; int m_iY; }; Coordinate::Coordinate(int x,int y) { m_iX = x; m_iY = y; } int Coordinate::getX() { return m_iX; } int Coordinate::getY() { return m_iY; } //成员函数实现负号运算符重载 Coordinate &Coordinate::operator-() { this->m_iX = -(this->m_iX);//m_iX = -m_iX; this->m_iY = -(this->m_iY); return *this;//返回的是一个对象 } int main() { Coordinate coor1(1,3); cout<<coor1.getX()<<","<<coor1.getY()<<endl; -coor1;//coor1.operator-();成员函数 cout<<coor1.getX()<<","<<coor1.getY()<<endl; return 0; }运行结果:
通过友元函数对负号运算符进行重载:
#include<iostream> using namespace std; /****************************************** 一元运算符重载 要求: 定义一个Coordinate坐标类 成员函数:构造、getX、getY,数据成员:m_iX,m_iY 1、负号运算符重载(成员函数,友元函数) 2、++运算符重载(前置++,后置++) *******************************************/ class Coordinate { friend Coordinate &operator-(Coordinate &c);//friend Coordinate &operator-(Coordinate c); //()内要传入参数,其实就是在成员函数重载中要传入的*this,所以应该是Coordinate的一个对象,为了传递效率,也可以传入一个对象的引用 public: Coordinate(int x,int y); int getX(); int getY(); private: int m_iX; int m_iY; }; Coordinate::Coordinate(int x,int y) { m_iX = x; m_iY = y; } int Coordinate::getX() { return m_iX; } int Coordinate::getY() { return m_iY; } Coordinate &operator-(Coordinate &c)//友元函数重载符号运算符 { c.m_iX = -c.m_iX; c.m_iY = -c.m_iY; return c; } int main() { Coordinate coor1(1,3); cout<<coor1.getX()<<","<<coor1.getY()<<endl; operator-(coor1);//-coor1; cout<<coor1.getX()<<","<<coor1.getY()<<endl; return 0; }运行结果:
运行结果:
1、“+号”运算符重载(成员函数,友元函数) 2、“<<”输出运算符重载 3、“[]索引”运算符重载
#include<iostream> using namespace std; /****************************************** 二元运算符重载 要求: 定义一个Coordinate坐标类 成员函数:构造、getX、getY,数据成员:m_iX,m_iY 1、“+号”运算符重载(成员函数,友元函数) 2、“<<”输出运算符重载 3、“[]索引”运算符重载 *******************************************/ class Coordinate { //“<<”输出运算符重载 friend ostream& operator<<(ostream &output,const Coordinate &c);//返回值是ostream //“+号”运算符通过友元函数重载 friend Coordinate operator+(const Coordinate &c1,const Coordinate &c2); public: Coordinate(int x,int y); //“+号”运算符通过成员函数重载,不能传引用,要传对象 //Coordinate operator+(const Coordinate &c); //“[]索引”运算符重载 int operator[](int index); int getX(); int getY(); private: int m_iX; int m_iY; }; Coordinate::Coordinate(int x,int y) { m_iX = x; m_iY = y; } int Coordinate::getX() { return m_iX; } int Coordinate::getY() { return m_iY; } /*“+号”运算符通过成员函数重载 Coordinate Coordinate::operator+(const Coordinate &c) { Coordinate temp(0,0); temp.m_iX = this->m_iX + c.m_iX; temp.m_iY = this->m_iY + c.m_iY; return temp; } */ //“+号”运算符通过友元函数重载 Coordinate operator+(const Coordinate &c1,const Coordinate &c2) { Coordinate temp(0,0); temp.m_iX = c1.m_iX + c2.m_iX; temp.m_iY = c1.m_iY + c2.m_iY; return temp; } //“<<”输出运算符重载 ostream& operator<<(ostream &output,const Coordinate &c)//返回值为ostream&,const Coordinate &c为要进行输出的对象 { output<<c.m_iX<<","<<c.m_iY<<endl; return output; } //“[]索引”运算符重载 int Coordinate::operator[](int index) { if(0 == index) { return m_iX; } if(1 == index) { return m_iY; } } int main() { Coordinate coor1(1,3); Coordinate coor2(2,4); Coordinate coor3(0,0); coor3 = operator+(coor1,coor2); //coor3 = coor1 + coor2; cout<<coor3.getX()<<","<<coor3.getY()<<endl;//3,7 operator<<(cout,coor1);//1,3 cout<<coor2;//2,4 cout<<coor2[0];//2 cout<<coor2[1];//4 return 0; }运行结果:
注:
“<<”输出运算符重载不能用成员函数进行重载,只能用友元函数进行重载;因为在成员函数中重载第一个参数为隐藏的*this,而“<<”输出运算符重载第一个参数为ostream &output“[]索引”运算符重载不能用友元函数进行重载,只能用成员函数进行重载;因为“[]索引”运算符重载第一个参数必须为*this,通过*this才能访问到该对象的数据赋值运算符重载函数不能被继承因为相较于基类,派生类往往要添加一些自己的数据成员和成员函数,如果允许派生类继承基类的赋值运算符重载函数,那么,在派生类不提供自己的赋值运算符重载函数时,就只能调用基类的,但基类版本只能处理基类的数据成员,在这种情况下,派生类自己的数据成员怎么办? 所以,C++规定,赋值运算符重载函数不能被继承。
赋值运算符重载函数只能是类的非静态的成员函数,不能是静态成员函数,也不能是友元函数
其实,之所以不是静态成员函数,是因为静态成员函数只能操作类的静态成员,不能操作非静态成员。如果我们将赋值运算符重载函数定义为静态成员函数,那么,该函数将无法操作类的非静态成员,这显然是不可行的。
下面是可重载的运算符列表:
双目算术运算符+ (加),-(减),*(乘),/(除),% (取模)关系运算符==(等于),!= (不等于),< (小于),> (大于>,<=(小于等于),>=(大于等于)逻辑运算符||(逻辑或),&&(逻辑与),!(逻辑非)单目运算符+ (正),-(负),*(指针),&(取地址)自增自减运算符++(自增),--(自减)位运算符| (按位或),& (按位与),~(按位取反),^(按位异或),,<< (左移),>>(右移)赋值运算符=, +=, -=, *=, /= , % = , &=, |=, ^=, <<=, >>=空间申请与释放new, delete, new[ ] , delete[]其他运算符()(函数调用),->(成员访问),,(逗号),[](下标)下面是不可重载的运算符列表:
.:成员访问运算符.*, ->*:成员指针访问运算符:::域运算符sizeof:长度运算符?::条件运算符#: 预处理符号还可参考:一文说尽C++赋值运算符重载函数(operator=)