文章目录
- 一、概念
- 1. 左值和右值
- 2. 运算符重载
- 3. 可以实现重载的运算符和不可以实现重载的运算符
- 二、双目运算符
- (一)说明
- (二)实现
- 1. 注意点
- 2. 算术运算符
- 成员函数版本
- 全局函数版本
- 3. 关系运算符
- 成员函数版本
- 全局函数版本
- 三、赋值类
- 四、单目类
- 五、递增和自减类
- (一)前自增自减运算符的重载
- (二)后自增自减运算符的重载
- 六、插入(>>)和提取(<<)运算符重载
一、概念
1. 左值和右值
左值:既可以在等号的左边也可以在等号的右边;
右值:只能放在等号的右边。
2. 运算符重载
给运算符赋予新的含义,让原本只能处理基本数据类型运算的运算符可以处理类对象之间的关系
运算符重载的本质就是函数重载
运算符重载的时候操作数的个数需要通过运算符来决定的
运算符版本分为全局函数版本和成员函数版本
3. 可以实现重载的运算符和不可以实现重载的运算符
二、双目运算符
(一)说明
L # R
L:左操作数
#:运算符
R:右操作数
对于左右操作数既可以是左值,也可以是右值
对于表达式结果必须是右值
(二)实现
1. 注意点
L # R
1. 成员函数版本
const 类名 operator#(const 类名& R)const{}第一个const修饰返回值,返回值是一个右值;第二个const修饰的是右操作数;第三个const修饰的是左操作数。
2. 全局函数版本
const 类名 operator#(const 类名 &L,const 类名 &R){};需要在类中声明为友元函数
2. 算术运算符
+
加 -
减 *
乘 /
除 %
取余
- 注: 返回值被const修饰,是为了避免返回值被修改的情况
成员函数版本
#include <iostream>
using namespace std;
class Complex{
public://构造函数Complex(){} //在实现运算符重载的函数中需要用到无参构造函数Complex(int a,int b):m_a(a),m_b(b){}//运算符重载函数声明const Complex operator +(const Complex &R)const;void print(){cout<<m_a<<'+'<<m_b<<'i'<<endl;}
private:int m_a; //实部int m_b; //虚部
};
//运算符重载函数定义
const Complex Complex::operator+(const Complex &R) const{Complex temp;temp.m_a=this->m_a+R.m_a;temp.m_b=this->m_b+R.m_b;return temp;
}int main()
{Complex m(3,4);Complex n(1,2);Complex r=m+n;r.print();return 0;
}
全局函数版本
#include <iostream>
using namespace std;
class Complex{
public://构造函数Complex(){} //在实现运算符重载的函数中需要用到无参构造函数Complex(int a,int b):m_a(a),m_b(b){}//运算符重载函数声明friend const Complex operator + (const Complex &L,const Complex &R);void print(){cout<<m_a<<'+'<<m_b<<'i'<<endl;}
private:int m_a; //实部int m_b; //虚部
};
//运算符重载函数定义
const Complex operator + (const Complex &L,const Complex &R){Complex temp;temp.m_a=L.m_a+R.m_a;temp.m_b=L.m_b+R.m_b;return temp;
}int main()
{Complex m(3,4);Complex n(1,2);Complex r=m+n;r.print();return 0;
}
3. 关系运算符
>
大于 <
小于 ==
等于 !=
不等于 >=
大于等于 <=
小于等于
成员函数版本
#include <iostream>
using namespace std;
class Complex{
public://构造函数Complex(){} //在实现运算符重载的函数中需要用到无参构造函数Complex(int a,int b):m_a(a),m_b(b){}//运算符重载函数声明bool operator >(const Complex &R)const;void print(){cout<<m_a<<'+'<<m_b<<'i'<<endl;}
private:int m_a; //实部int m_b; //虚部
};
//运算符重载函数定义
bool Complex::operator>(const Complex &R) const{if(this->m_a>R.m_a && this->m_b>R.m_a)return true;return false;
}int main()
{Complex m(3,4);Complex n(1,2);if(m>n)cout<<"m>n"<<endl;elsecout<<"m<=n"<<endl;return 0;
}
全局函数版本
#include <iostream>
using namespace std;
class Complex{
public://构造函数Complex(){} //在实现运算符重载的函数中需要用到无参构造函数Complex(int a,int b):m_a(a),m_b(b){}//运算符重载函数声明friend bool operator >(const Complex &L,const Complex &R);void print(){cout<<m_a<<'+'<<m_b<<'i'<<endl;}
private:int m_a; //实部int m_b; //虚部
};
//运算符重载函数定义
bool operator >(const Complex &L,const Complex &R){if(L.m_a>R.m_a && L.m_b>R.m_a)return true;return false;
}int main()
{Complex m(3,4);Complex n(1,2);if(m>n)cout<<"m>n"<<endl;elsecout<<"m<=n"<<endl;return 0;
}
三、赋值类
+=
-=
/=
%=
&=
^=
‘<<=’ >>=
L # R
左操作数只能是一个左值
右操作数既可以是一个左值,也可以是一个右值
返回值是左操作数本身
成员函数版:
类名 &operator#(const 类名 &R){}
全局函数版:
类名 &operator#(类名 &L, const 类名 &R){}
- 注:赋值运算符’
=
'只能使用成员函数版本,因为编译器提供的特殊的成员函数,拷贝复制函数就是=
运算符重载;
且两个版本的重载函数不能同时出现,否则会造成歧义。
四、单目类
-
(负) ~
(取反) !
(非)
表达式:
#O
操作数既可以是一个左值,也可以是一个右值
表达式的结果是一个右值
成员函数版:
const 类名 operator#(void)const;
第一个const是用来修饰返回值的
第二个const是用来修饰操作数
全局函数版:
const 类名 operator#(const 类名 &O)
五、递增和自减类
++a
a++
a--
--a
(一)前自增自减运算符的重载
表达式:
#O
操作数是一个左值
返回值是一个左值
成员函数版本:
类名& operator#(void);
全局函数版本:
类名 operator#(类名& O)
前自增自减是先自增自减然后返回对象本身
Complex &Complex::operator++(void)
{++this->m_a;++this->m_b;return *this;
}
- 注:此处返回值是一个左值,可以修改,因此不能用const修饰
(二)后自增自减运算符的重载
表达式:
#O
操作数是一个左值
返回值是一个右值
成员函数版本:
const 类名& operator#(哑元);
全局函数版本:
const 类名 operator#(类名& O,哑元)
后自增自减需要先返回值然后再做自增或自减,因此需要一个临时变量保存对象当前的值,然后对象再进行自增或者自减,运算符重载函数返回的是临时变量,当函数执行完毕后,临时变量的空间就被释放了,因此返回值是一个右值
const Complex Complex::operator ++(int){Complex temp;temp.m_a=this->m_a++;temp.m_b=this->m_b++;return temp;
}
- 注:此处返回值是一个右值,不可以修改,因此使用const修饰
六、插入(>>)和提取(<<)运算符重载
#include <iostream>
istream:输入流类 cin
ostream:输出流类 cout
在对插入运算符和提取运算符做操作时要使用全局函数版本
istream& operator >> (istream &in,类名 &R);
左操作数是cin;
右操作数既可以是左值,也可以是右值;
返回值是一个左值,返回值类型是istream&
ostream& operator <<(ostream &out,类名 &R);
左操作数是cout;
右操作数既可以是左值,也可以是右值
返回值是一个左值,返回值类型是ostream&
#include <iostream>
using namespace std;
class Complex{
public://构造函数Complex(){} //在实现运算符重载的函数中需要用到无参构造函数Complex(int a,int b):m_a(a),m_b(b){}//运算符重载函数声明friend ostream &operator<<(ostream &out,Complex &O);friend istream &operator>>(istream &in,Complex &O);void print(){cout<<m_a<<'+'<<m_b<<'i'<<endl;}
private:int m_a; //实部int m_b; //虚部
};
//运算符重载函数定义
ostream &operator<<(ostream &out,Complex &O){char op;if(O.m_b<0)op='-';elseop='+';out<<O.m_a<<op<<O.m_b<<'i';return out;
}
istream &operator>>(istream &in,Complex &O){in>>O.m_a>>O.m_b;return in;
}int main()
{Complex m(3,4);cout<<m<<endl;Complex mm(0,0);cin>>mm;cout<<mm<<endl;return 0;
}