重载运算符
1.不能重载的5个运算符
. .* :: ?: sizeof
2重载运算符的限制
①不改变运算符的优先级
②不改变运算符的结合性
③不改变运算符所需要的操作数
3.运算符重载是一种特殊的成员函数或友元函数
成员函数语句格式
类型 类名::operator op(参数表){ }
类型指函数的返回类型 类名是要重载该运算符的类 op是要重载的运算符 函数名是operator op 参数表列出该运算符所需要的 操作数
4.一元运算符(一个操作数)
Objectop或op Object
(1)当重载为成员函数时,编译器解释为Object operator op()
函数operator op所需的操作数由对象Object通过this指针隐含传递,所以参数表为空
(2)重载为友元函数,解释为operator op (Object)
函数operator op所需的操作数由参数表的参数Object提供
5.二元运算符(两个操作数)
二元运算符要求有左右两个操作数ObjectL op ObjectR
(1)重载为成员函数,解释为ObjectL . operator op (ObjectR )
左操作数由对象ObjectL通过this指针传递,右操作数由参数ObjectR传递(一般用传引用&)
(2)重载为友元函数,解释为operator op ( ObjectL,ObjectR )
左右操作数都由参数传递
注:用成员函数或友元函数重载关键区别 成员函数有this指针 友元函数没有this指针
6.用成员函数重载运算符
当一元运算符的操作数,或二元运算符的左操作数是该类的一个对象时,重载运算符一般定义为成员函数
成员运算符函数的原型在类的内部声明格式如下:
class Time
{
public:
Time( ){minute=0;sec=0;}
Time(int m,int s):minute(m),sec(s){ }
Time operator++( ); //声明前置自增运算符“++”重载函数
Time operator++(int); //声明后置自增运算符“++”重载函数
private:
int minute;
int sec;
};
Time Time∷operator++( ) //定义前置自增运算符“++”重载函数
{
if(++sec>=60) {
sec-=60; //满60秒进1分钟
++minute;
}
return *this; //返回当前对象值
}
Time Time∷operator++(int) //定义后置自增运算符“++”重载函数
{
Time temp(*this);
sec++;
if(sec>=60) {
sec-=60;
++minute;
}
return temp; //返回的是自加前的对象
}
7.友元重载
#include<iostream>
using namespace std;
class Complex
{ public:
Complex( double r =0, double i =0 ) { Real = r ; Image = i ; }
Complex(int a) { Real = a ; Image = 0 ; }
void print() const ;
friend Complex operator+ ( const Complex & c1, const Complex & c2 ) ;
friend Complex operator- ( const Complex & c1, const Complex & c2 ) ;
friend Complex operator- ( const Complex & c ) ;
private:
double Real, Image ;
};
Complex operator + ( const Complex & c1, const Complex & c2 )
{ double r = c1.Real + c2.Real ; double i = c1.Image+c2.Image ;
return Complex ( r, i ) ;
}
Complex operator - ( const Complex & c1, const Complex & c2 )
{ double r = c1.Real - c2.Real ; double i = c1.Image - c2.Image ;
return Complex ( r, i ) ;
}
Complex operator- ( const Complex & c )
{ return Complex ( -c.Real, - c.Image ) ; }
void Complex :: print() const
{ cout << '(' << Real << " , " << Image << ')' << endl ; }
注: 成员运算符函数与友元运算符函数的比较
8.典型运算符重载
(1)++与--
- 前置方式: ++Aobject --Aobject
- 后置方式: Aobject++ Aobject --
#include<iostream>
using namespace std;
class Increase
{ public :
Increase ( ) { value=0; }
void display( ) const { cout<<value<<'\n'; } ;
Increase operator ++ ( ) ; // 前置
Increase operator ++ ( int ) ; // 后置
private: unsigned value ;
};
Increase Increase :: operator ++ ( )
{ value ++ ; return *this ; }
Increase Increase :: operator ++ ( int )
{ Increase temp; temp.value = value ++ ; return temp; }
int main( )
{ Increase a , b , n ; int i ;
for ( i = 0 ; i < 10 ; i ++ ) a = n ++ ;
cout <<"n= " ; n.display( ) ; cout <<"a= " ; a.display( ) ;
for ( i = 0 ; i < 10 ; i ++ ) b = ++ n ;
cout << "n= " ; n.display( ) ; cout << "b= " ; b.display( ) ;
}
友元重载++
#include<iostream>
using namespace std;
class Increase
{ public :
Increase ( ) { value=0; }
void display( ) const { cout<<value<<'\n'; } ;
friend Increase operator ++ ( Increase & ) ; // 前置
friend Increase operator ++ ( Increase &, int ) ; // 后置
private: unsigned value ;
};
Increase operator ++ ( Increase & a )
{ a.value ++ ; return a ; }
Increase operator ++ ( Increase & a, int )
{ Increase temp(a); a.value ++ ; return temp; }
int main( )
{ Increase a , b , n ; int i ;
for ( i = 0 ; i < 10 ; i ++ ) a = n ++ ;
cout <<"n= " ; n.display( ) ; cout <<"a= " ; a.display( ) ;
for ( i = 0 ; i < 10 ; i ++ ) b = ++ n ;
cout << "n= " ; n.display( ) ; cout << "b= " ; b.display( ) ;
}
(2)重载赋值运算符=
(3)重载运算符[]和()
- []运算符用于访问数据对象的元素
其中,x是X类的对象,则调用函数的表达式:x[k] 被解释为:x.operator[](K)
-
()运算符用于函数调用重载格式 类型 类 :: operator() ( 参数表 ) ;例设 x 是类 X 的一个对象,则表达式x ( arg1, arg2, … )可被解释为x . operator () (arg1, arg2, … )
(4)重载<<和>>(只能重载为友元函数)
- 重载输出运算符“<<”(只能被重载成友元函数,不能重载成成员函数)
- 重载输入运算符“>>” (只能被重载成友元函数)
#include<iostream>
#include<cstdlib>
using namespace std;
class vector
{ public :
vector( int size =1 ) ; ~vector() ;
int & operator[] ( int i ) ;
friend ostream & operator << ( ostream & output , vector & ) ;
friend istream & operator >> ( istream & input, vector & ) ;
private :
int * v ; int len ;
};
int main(){
int k ; cout << "Input the length of vector A :\n" ; cin >> k ;
vector A( k ) ; cout << "Input the elements of vector A :\n" ;
cin >> A ; cout << "Output the elements of vector A :\n" ;
cout << A ;
}
vector::vector( int size )
{ if (size <= 0 || size > 100 )
{ cout << "The size of " << size << " is null !\n" ; exit( 0 ) ; }
v = new int[ size ] ; len = size ;
}
vector :: ~vector() { delete[] v ; len = 0 ; }
int & vector :: operator [] ( int i )
{ if( i >=0 && i < len ) return v[ i ] ;
cout << "The subscript " << i << " is outside !\n" ; exit( 0 ) ;
}
ostream & operator << ( ostream & output, vector & ary )
{ for(int i = 0 ; i < ary.len ; i ++ ) output << ary[ i ] << " " ;
output << endl ;
return output ;
}
istream & operator >> ( istream & input, vector & ary )
{ for( int i = 0 ; i < ary.len ; i ++ ) input >> ary[ i ] ;
return input ;
}
9.心得体会
使用重载运算符后,程序更加直观简洁,能够自己定义需要的操作类型,但是在写ATM程序中想要尝试使用重载运算符,不知道如何下手,不知道应该改哪些部分,对着课本现有的程序改了一小部分,但是有的地方没有调通,对于重载运算符的使用规则和用法还是有很多疑问。主要存在的问题有使用成员函数和友元函数的用法区别,应该注意哪些情况使用友元 哪些使用成员函数,语法规则如何。在判断时间时用重载运算符<简化代码,更加直观,一个数据对象整体输入整体输出 用<< 全输入,用>>全输出。在调好一个程序后,可以尝试着使用重载运算符简化程序,使程序功能更加清晰明了,多加练习,逐渐熟悉重载的使用语法形式,尤其是重载<和<<与>>,当然前提是要掌握成员函数与友元函数的使用语法规则。现在还没有体会到重载运算符的突出之处,尝试在程序中使用一些重载,慢慢领悟它的独到之处。