c++第6天--运算符重载
- 运算符重载概述
- 运算符重载规则
- 友元、成员函数重载运算符
- 运算符重载的限制
运算符重载概述
自定义的类的对象无法像基本类型的数据那样运算与输出。
运算符重载本质上就是定义一个特殊的函数,这个函数的名字就是operater加上要重载的字符,其一般的样式就是下面的形式:
返回类型 operator运算符(参数列表) {
// 函数体
}
重载运算符并没有改变其原来的功能,只是增加了针对自定义数据类型的运算功能。
一下为一个例子,实现复数类重载+运算符
#include<iostream>
using namespace std;class Complex{
private:double real;double imag;
public:Complex(double real = 0,double imag = 0) : real(real),imag(imag) {}Complex operator+(const Complex& other){return Complex(real + other.real,imag + other.imag);}friend Complex operator+(const Complex& first,const Complex& second);
void display()
{cout << real;if(imag > 0)cout << "+" << imag << "i";else if(imag < 0)cout << imag << "i";cout << endl;
}
};Complex operator+(const Complex& first,const Complex& second)
{return Complex(first.real + second.real,first.imag + second.imag);
}
int main()
{Complex c1(1,2),c2(3,-4);Complex c3 = c1 + c2;Complex c4 = c1 + c2;cout << "c1 = ";c1.display();cout << "c2 = ";c2.display();cout << "c3 = ";c3.display();cout << "c4 = ";c4.display();return 0;
}
运算符重载的方式:
有两种,分别是成员函数重载与友元函数重载
那么什么是成员函数重载? 运算符重载函数可以作为类的成员函数,在成员的函数重载中,this指针会隐式地调用该运算符的对象,因此参数列表中的参数个数会比运算符时机操作数少一个(一元运算符无参数,二元运算符有一个参数)
//运算符重载有两种方式,一种是成员运算符重载,一种是友元函数重载
#include<iostream>
using namespace std;class Complex{
private:double real;double imag;
public:Complex(double real = 0,double imag = 0) : real(real),imag(imag) {}//成员函数重载改+运算符Complex operator+(const Complex& other) const{return Complex(real + other.real,imag + other.imag);}void display() const{cout << real;if(imag > 0) cout << " + " << imag << "i";else if(imag < 0)cout << "-" << -imag << "i";cout << endl;}
};int main()
{Complex c1(2,3),c2(4,-5);Complex c3 = c1 + c2;cout << "c1 = "; c1.display();cout << "c2 = "; c2.display();cout << "c3 = "; c3.display();return 0;
}
友元函数重载:友元函数不属于类的成员函数,但是可以访问类的私有成员,使用友元函数重载时,参数列表中的参数个数和运算符的实际操作数相同。
//现在写一个友元函数的实现函数运算符重载+号
#include<iostream>
using namespace std;class Complex{
private:double real;double imag;
public:Complex(double real = 0,double imag = 0) : real(real),imag(imag) {}//友元函数重载+运算符friend Complex operator+(const Complex& c1,const Complex& c2);void display() const{cout << real;if(imag > 0)cout << "+" << imag << "i";else if(imag < 0)cout << imag << "i";cout << endl;}
};Complex operator+(const Complex& c1,const Complex& c2){return Complex(c1.real + c2.real, c1.imag + c2.imag);}int main(){Complex c1(2,3),c2(4,-5);Complex c3 = c1 + c2;cout << "c1 = "; c1.display();cout << "c2 = "; c2.display();cout << "c3 = "; c3.display();return 0;}
运算符重载的限制:
* 不能改变运算符的优先级和结合性,运算符重载只是重新定义了运算符对于自定义类型的操作行为,但不能改变运算符原有的优先级和结合性。
* 不能创造新的运算符:只能对已有的运算符进行重载,不能创建新的运算符。
* 至少有一个操作数是自定义类型:运算符重载主要是为了让自定义类型能使用运算符,因此运算符的操作数中至少有一个是自定义的类对象。
//一个大练习实现重载+重载-重载==
#include<iostream>
using namespace std;class Point{
private:int x;int y;
public:Point(int x = 0,int y = 0) : x(x),y(y) {}//成员函数重载 + 运算符Point operator+(const Point& other) const{return Point(x + other.x,y + other.y);}//友元函数重载 - 运算符friend Point operator-(const Point& p1,const Point& p2); //全局函数重载 == 运算符friend bool operator==(const Point& p1,const Point& p2);//输出坐标void display() const{cout << "(" << x << ", " << y << ")" << endl;}
};//友元函数实现 - 运算符
Point operator-(const Point& p1,const Point& p2){return Point(p1.x - p2.x, p1.y - p2.y);
}//全局函数实现 == 运算符
bool operator==(const Point& p1,const Point& p2){return p1.x == p2.x && p1.y == p2.y;
}
int main() {Point p1(3, 4), p2(1, 2);Point p3 = p1 + p2;Point p4 = p1 - p2;cout << "p1 = "; p1.display();cout << "p2 = "; p2.display();cout << "p3 = "; p3.display();cout << "p4 = "; p4.display();cout << "p1 " << (p1 == p2 ? "等于" : "不等于") << " p2" << endl;return 0;
}