一、什么是运算符重载
运算符重载是指对原本有固定语义的运算符进行重新定义,赋予它们适用于自定义类型或数据结构的意义。C++允许对所有的运算符进行重载,包括算术、比较、逻辑运算符等。
class Vector{ public: int x,y,z; Vector(int a=0,int b=0,int c=0){ x=a,y=b,z=c; } Vector operator + (const Vector &other) const{ return Vector(x+other.x,y+other.y,z+other.z); } };
如上所示,重载了加号运算符,使之可以对自定义类型进行运算。
二、为什么需要运算符重载
运算符重载能够提高代码的可读性和灵活性。使用运算符重载可以使得代码更加自然而直观,易于阅读和理解。例如,使用Vector+Vector运算符,比使用add(Vector a,Vector b)函数更接近日常语言表述。
此外,运算符重载也提高了代码的灵活性。可以定义新的类型及其运算符,以适用于不同的应用场景。例如在图像处理中,可以定义一种自定义的Matrix类型,并重载其乘法运算符,以方便矩阵乘法的计算。
三、运算符重载的细节和注意点
1. 运算符重载与成员函数和非成员函数的选择
在定义运算符重载函数时,可以将其定义为成员函数或非成员函数。成员函数的第一个参数是*this指针,代表调用对象本身,非成员函数需要传入对应的参数。一般地,如果运算符作用于两个同类型的对象,应该定义为成员函数;如果运算符作用于不同类型的对象,应该定义为非成员函数。
class Vector{ public: int x,y,z; Vector(int a=0,int b=0,int c=0){ x=a,y=b,z=c; } friend Vector operator + (const Vector &a,const Vector &b){ return Vector(a.x+b.x,a.y+b.y,a.z+b.z); } };
2. 运算符重载的形参输入输出
运算符重载函数的参数列表可以根据需求进行修改,允许输入输出多个参数。需要注意的是,输入参数通常是常量引用,以避免拷贝构造造成的性能损耗;输出参数需要用引用形式,以便改变对象本身。
class Matrix{ public: int mat[3][3]; Matrix(){} Matrix(int a[][3]){ memcpy(mat,a,sizeof(mat)); } friend Matrix operator * (const Matrix &a,const Matrix &b){ Matrix res; memset(res.mat,0,sizeof(res.mat)); for(int i=0;i<3;i++){ for(int j=0;j<3;j++){ for(int k=0;k<3;k++){ res.mat[i][j]+=a.mat[i][k]*b.mat[k][j]; } } } return res; } };
3.运算符重载的返回值类型
运算符重载函数除了应用于特定类型变量上的常见形式之外,还可以作为其他运算符重载函数过程中的返回值类型。返回值类型可以是各种数据类型,包括自定义类型。
class Box{ public: int length,width,height; Box(){} Box(int a,int b,int c):length(a),width(b),height(c){} friend bool operator < (const Box &a,const Box &b){ return a.length*a.width*a.height4.运算符重载的友元函数
如果重载运算符需要访问类的私有成员,就需要定义为友元函数。友元函数可以访问声明友元函数的类的私有成员变量和函数,但是它不是该类的成员函数。
class Fraction{ public: Fraction(int n=0,int d=1):num(n),den(d){} friend Fraction operator + (const Fraction &a,const Fraction &b){ int n=a.num*b.den+b.num*a.den,d=a.den*b.den; int g=gcd(n,d); return Fraction(n/g,d/g); } private: int num,den; int gcd(int a,int b){ return b==0?a:gcd(b,a%b); } };四、总结
运算符重载是C++中一种强大的语言特性,可以提高程序的可读性和灵活性。在使用运算符重载时需要注意一些细节问题,例如运算符重载函数的返回类型和参数类型,非成员函数和成员函数的选择等。通过合理利用运算符重载,可以使代码更加简洁、易读、易懂。