教程:https://www.imooc.com/learn/477
运算符重载:给原有运算符赋予新功能
上图,用+连接多个字符串使其拼接成一个字符串str3,打印的时候可以直接把这个字符串打印出来,则这个字符串进行了多个运算符的重载,+也进行了重载,cout也进行了重载,=也进行了重载
上图,原来+并不具备这样子把两个坐标相加的功能,需要对其进行重载,要这样子把坐标输出,也要对输出运算符进行重载
运算符重载的本质:函数重载
关键字:operator
一元运算符重载(这里以-、++举例)
一元运算符:这个符号只与一个操作数进行运算
如:+(加法)是二元运算符,因为需要两个操作数,但把+放在一个操作数前面,就是一元运算符,就像-放在一个操作数前面,也是一元运算符,对操作数取反
友元函数重载:在类中定义一个友元函数,这个友元函数是一个全局函数,用这个友元函数进行运算符重载,从而实现一个符号的理想功能
成员函数重载:实际上就是定义一个成员函数
上图标红句子是对-进行运算符重载,()里没有参数是因为是一元运算符,而且是作为类的成员函数存在的,所以不需要传任何参数,但里面是有一个隐性的this指针的,而这个隐性的this指针就是其操作数,如下图,将每个数据成员取反,再重新赋值给他本身:
使用:
看到-coor1;
计算机会自动解释为注释,相当于一个函数的调用
友元函数的重载
用friend全局声明一个函数“operator-”
传入的参数是Coordinate的引用,返回值也是Coordinate的引用
实现的时候,通过这个引用变量,分别对每一个数据成员取反,并赋值给本身,用this返回
实现:
对比:成员函数重载,是coor1.operator-();
友元函数重载,是operator-(coor1);
++符号的重载
前置++符号重载:将++写在操作数前面
后置++符号重载:
注意:1、返回值不是引用,而是Coordinate的一个对象(前置的是引用)2、operator++后一定要传入一个int,作为一个标识,表示当前operator++做的是后置重载。在使用时,这个int不用传入任何值,传了也没意义,因为不会使用到
Coordinate old(*this);
为保证有一个旧的值,先定义一个临时对象old,将当前的值保存到临时兑现old中。最后通过return old;
返回
所以如果接收到后置++的值,那也是++前的值,下行代码再去使用这个值的时候,这个值才会发生变化
使用:
传入的0是个标识
编码示例:
负号成员函数的重载:
当前采用的是引用的方式:
Coordinate.h
#ifndef COORDINATE_H
#define COORDINATE_H
#include <iostream>
using namespace std;
class Coordinate
{
public:
Coordinate(int x, int y);
Coordinate &operator-();
int getX();
int getY();
private:
int m_iX;
int m_iY;
};
#endif // ! COORDINATE_H
Coordinate.cpp
#include "Coordinate.h"
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_iY = -m_iY; //两种写法都可以
return *this;
}
demo.cpp
#include "Coordinate.h"
#include <iostream>
using namespace std;
int main()
{
Coordinate coor1(1, 3);
cout << coor1.getX() << " , " << coor1.getY() << endl;
-coor1; //相当于 coor1.operator-();
cout << coor1.getX() << " , " << coor1.getY() << endl;
return 0;
}
友元函数的负号重载:
Coordinate.h
#ifndef COORDINATE_H
#define COORDINATE_H
#include <iostream>
using namespace std;
class Coordinate
{
friend Coordinate &operator-(Coordinate &c); //括号内的参数就是成员函数运算符重载括号中的this,在这里体现为Coordinate的一个对象。可以写Coordinate c 为了传递效率,也可以再加个&
public:
Coordinate(int x, int y);
//Coordinate &operator-(); //成员函数运算符重载
int getX();
int getY();
private:
int m_iX;
int m_iY;
};
#endif // ! COORDINATE_H
Coordinate.cpp
#include "Coordinate.h"
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_iY = -m_iY; //两种写法都可以
return *this; */
Coordinate &operator-(Coordinate &c) //友元函数运算符重载 ,是全局的,不属于任何一个类
{
c.m_iX = -c.m_iX;
c.m_iY = -c.m_iY;
return c;
}
demo.cpp (使用没有变,只是改了一下注释)
#include "Coordinate.h"
#include <iostream>
using namespace std;
int main()
{
Coordinate coor1(1, 3);
cout << coor1.getX() << " , " << coor1.getY() << endl;
-coor1; //相当于 operator-(coor1);
cout << coor1.getX() << " , " << coor1.getY() << endl;
return 0;
}
前置++成员函数的重载:
Coordinate.h
#ifndef COORDINATE_H
#define COORDINATE_H
#include <iostream>
using namespace std;
class Coordinate
{
friend Coordinate &operator-(Coordinate &c); //括号内的参数就是成员函数运算符重载括号中的this,在这里体现为Coordinate的一个对象。可以写Coordinate c 为了传递效率,也可以再加个&
public:
Coordinate(int x, int y);
Coordinate &operator++(); //前置++成员函数的重载
//Coordinate &operator-(); //成员函数运算符重载
int getX();
int getY();
private:
int m_iX;
int m_iY;
};
#endif // ! COORDINATE_H
Coordinate.cpp
#include "Coordinate.h"
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_iY = -m_iY; //两种写法都可以
return *this; */
Coordinate &Coordinate::operator++() //前置++,返回的值是++之后的值
{
m_iX++; //++m_iX;
m_iY++; //++m_iY; 两种写法都可以
return *this;
}
Coordinate &operator-(Coordinate &c) //友元函数运算符重载 ,是全局的,不属于任何一个类
{
c.m_iX = -c.m_iX;
c.m_iY = -c.m_iY;
return c;
demo.cpp
#include "Coordinate.h"
#include <iostream>
using namespace std;
int main()
{
Coordinate coor1(1, 3);
cout << coor1.getX() << " , " << coor1.getY() << endl;
++ coor1;
cout << coor1.getX() << " , " << coor1.getY() << endl;
//-coor1; //相当于 operator-(coor1);
//cout << coor1.getX() << " , " << coor1.getY() << endl;
return 0;
}
后置++成员函数的重载:
Coordinate.h
#ifndef COORDINATE_H
#define COORDINATE_H
#include <iostream>
using namespace std;
class Coordinate
{
friend Coordinate &operator-(Coordinate &c); //括号内的参数就是成员函数运算符重载括号中的this,在这里体现为Coordinate的一个对象。可以写Coordinate c 为了传递效率,也可以再加个&
public:
Coordinate(int x, int y);
Coordinate &operator++(); //前置++成员函数的重载
Coordinate operator++(int); //后置++成员函数的重载 返回的是Coordinate的对象而不是引用,因为后置++,返回的是++之前的值,下一句再使用的时候才是++后的
//Coordinate &operator-(); //成员函数运算符重载
int getX();
int getY();
private:
int m_iX;
int m_iY;
};
#endif // ! COORDINATE_H
Coordinate.cpp
#include "Coordinate.h"
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_iY = -m_iY; //两种写法都可以
return *this; */
Coordinate &Coordinate::operator++() //前置++,返回的值是++之后的值
{
m_iX++; //++m_iX;
m_iY++; //++m_iY; 两种写法都可以
return *this;
}
Coordinate Coordinate::operator++(int)
{
Coordinate old(*this); //临时对象,直接赋值:把this放进去,此时用到拷贝构造函数,因为没有在用到类型为指针的数据成员,也没有再类中实例化对象,所以用默认拷贝构造函数,如果做了特殊处理,可能要重载拷贝构造函数
this->m_iX++;
this->m_iY++;
return old; //注意是old不是this,以实现在当前表达式得到的是++前的值,在表达式之后运行的对象是++后的值
}
Coordinate &operator-(Coordinate &c) //友元函数运算符重载 ,是全局的,不属于任何一个类
{
c.m_iX = -c.m_iX;
c.m_iY = -c.m_iY;
return c;
}
demo.cpp
#include "Coordinate.h"
#include <iostream>
using namespace std;
int main()
{
Coordinate coor1(1, 3);
cout << coor1.getX() << " , " << coor1.getY() << endl;
cout << (coor1++).getX() << " , "; //coor1++前的值,此时拿到的是1
cout << (coor1++).getY() << endl; //coor1在上行以++过一次,此时拿到的是上行++过的,即4
cout << coor1.getX() << " , " << coor1.getY() << endl; //本行得到的是经过上两行++后的
return 0;
}
二元运算符重载
+号成员函数重载:
参数是第二个加数,第一个加数默认是当前对象
定义一个Coordinate类型的临时对象,coor的和当前的(this)相加赋给temp
标红句的+已经重载
+号友元函数重载:
定义:
写了const就不能改c1、c2的值
实现:
使用:
<<号运算符:
定义:
声明为友元函数,返回值必须是ostream&,传入的第一个参数也必须是ostream &out(out可改),第二个参数是输出的对象
实现:
用ostream &out这个对象替代输出语句的cout,其他的写法不变,return out(out可变)也是必须的
使用:
从以上可理解,cout是ostream的一个对象
**输出运算符不可以采用成员函数重载,只能用友元函数。**原因:由+成员函数重载知,第一个参数是当前对象。对于输出运算符来说,第一个对象必须是ostream,这就意味着第一个参数不能是this指针,即不能是当前对象。
[]索引运算符:
声明:
实现:
如果两个都不是,应该抛出异常(上图没有处理)
使用:
传入0打印X,传入1打印Y
索引运算符不可以采用友元函数重载,必须用成员函数重载,友元函数重载第一个参数可以是成员函数重载中的this指针,也可以是其他的值,但作为索引运算符,第一个参数必须是this指针,因为只有第一个参数是this指针,才可以传入索引,才能使这个索引表达的是当前的对象中的成员
二次运算符重载编码示例:
+号运算符成员函数重载:
Coordinate.h
#ifndef COORDINATE_H
#define COORDINATE_H
#include <iostream>
using namespace std;
class Coordinate
{
public:
Coordinate(int x, int y);
Coordinate operator+(Coordinate &c); //+号运算符成员函数重载,第一个参数是this指针,第二个参数是()内容
int getX();
int getY();
private:
int m_iX;
int m_iY;
};
#endif // ! COORDINATE_H
Coordinate.cpp
#include "Coordinate.h"
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+(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;
}
demo.cpp
#include "Coordinate.h"
#include <iostream>
using namespace std;
int main()
{
Coordinate coor1(1, 3);
Coordinate coor2(2, 4);
Coordinate coor3(0, 0);
coor3 = coor1 + coor2;
cout << coor3.getX() << " , " << coor3.getY() << endl;
return 0;
}
+号运算符友元函数重载:
修改:
Coordinate.h
#ifndef COORDINATE_H
#define COORDINATE_H
#include <iostream>
using namespace std;
class Coordinate
{
friend Coordinate operator+(Coordinate c1, Coordinate c2); //+号运算符友元函数重载
public:
Coordinate(int x, int y);
int getX();
int getY();
private:
int m_iX;
int m_iY;
};
#endif // ! COORDINATE_H
Coordinate.cpp
#include "Coordinate.h"
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 c1, 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;
}
输出运算符的重载:
Coordinate.h增加:
friend ostream &operator<<(ostream &output, Coordinate &coor);
Coordinate.cpp增加:
ostream &operator<<(ostream &output, Coordinate &coor)
{
output << coor.m_iX << "," << coor.m_iY;
return output;
}
demo.cpp
#include "Coordinate.h"
#include <iostream>
using namespace std;
int main()
{
Coordinate coor1(1, 3);
Coordinate coor2(2, 4);
Coordinate coor3(0, 0);
coor3 = coor1 + coor2;
cout << coor3 << endl;
return 0;
}
[]索引运算符的重载:
Coordinate.h在public下增加:
int operator [](int index);
Coordinate.cpp增加:
int Coordinate::operator [](int index)
{
if (index == 0)
{
return m_iX;
}
if (index == 1)
{
return m_iY;
}
}
demo.cpp
#include "Coordinate.h"
#include <iostream>
using namespace std;
int main()
{
Coordinate coor1(1, 3);
Coordinate coor2(2, 4);
Coordinate coor3(0, 0);
coor3 = coor1 + coor2;
cout << coor3 [0]<< endl; //输出m_iX
cout << coor3[1] << endl; //输出m_iY
return 0;
}
综合:
#include <iostream>
using namespace std;
/**
* 定义Coordinate类
* 数据成员:m_iX,m_iY
* 成员函数:构造函数
* 重载--运算符,重载+运算符
*/
class Coordinate
{
public:
Coordinate(int x, int y)
{
m_iX = x;
m_iY = y;
}
// 前置--运算符重载
Coordinate &operator--()
{
m_iX--;
m_iY--;
return *this;
}
// 后置--运算符重载
Coordinate &operator--(int)
{
Coordinate old(*this);
this->m_iX--;
this->m_iY--;
return old;
}
// +号运算符重载
Coordinate operator+(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;
}
public:
int m_iX;
int m_iY;
};
int main(void)
{
Coordinate coor1(1, 3);
Coordinate coor2(2, 4);
Coordinate coor3(0, 0);
coor1--;
--coor2;
coor3 = coor1 + coor2;
cout << coor3.m_iX << endl;
cout << coor3.m_iY << endl;
return 0;
}
来源:CSDN
作者:DAYTOY_
链接:https://blog.csdn.net/weixin_45550460/article/details/104397293