C++ 一元、二元运算符重载

    xiaoxiao2022-07-04  134

    运算符重载,就是对已有的运算符重新进行定义,赋予其另一种功能,使他适应不同的数据类型。

    运算符重载的本质:函数重载       关键字: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; }

    运行结果:

    前置++、后置++重载

    #include<iostream> using namespace std; Coordinate { public: Coordinate(int x,int y); Coordinate &operator++();//前置++的运算符重载,返回的是一个Coordinate的引用 Coordinate operator++(int);//后置++的运算符重载,参数int只是为了表示当前的++是后置++ //返回的是一个对象而不是引用,是因为后置++是在下一行代码再去访问这个对象的时候才会返回++之后的值,如果返回引用的话,函数结束后,引用就会被释放 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++()//前置++ { ++m_iX; ++m_iY; return *this; } Coordinate Coordinate::operator++(int)//后置++ { Coordinate old(*this);//利用默认拷贝构造函数构造一个临时对象old,将++之前的值存储在临时对象old中 this->m_iX++; this->m_iY++; return old;//当前这个表达式是他++之前的值,下一行代码再去访问这个对象的时候,才是++之后的值 } int main() { Coordinate coor1(1,3); cout<<coor1.getX()<<","<<coor1.getY()<<endl;//1,3 coor1.operator++(0);//参数0只是标识是后置++ cout<<coor1.getX()<<","<<coor1.getY()<<endl;//2,4 cout<<(coor1++).getX()<<",";//2 cout<<(coor1++).getY()<<endl;//5 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=) 

     

    最新回复(0)