运算符重载的实质
运算符重载:对已有的运算符赋予多重含义,实质是函数重载,它提供了C++的可扩展性。
实现机制
转化: 运算表达式转化为对运算符函数的调用, 运算对象转化为运算符函数的实参。 编译系统对重载运算符的选择,遵循函数重载的
选择原则:目前可以简单地理解为通过函数的参数表判断调用的是重载中的哪个函数。
运算符重载规则
重载运算符的限制
不能重载的运算符
成员访问运算符. ‘ . ’ 在类中对任何成员都有意义,已经成为标准用法。
作用域运算符 ::
成员指针访问运算符 .*
为了处理特殊情况而设计,在一般程序设计中通常不需要用到条件运算符 ? :
这个运算符对于类对象来说没有实际意义,相反还会引起歧义
Sizeof 不要当作普通的运算符
可以重载的运算符
算术运算符:+,-,,/,%,++,–;
位操作运算符:&,|,~,^(位异或),<<(左移),>>(右移);
逻辑运算符:!,&&,||;
比较运算符:<,>,>=,<=,==,!=;
赋值运算符:=,+=,-=,=,/=,%=,&=,|=,^=,<<=,>>=;
其他运算符:[] , () , -> , ,(逗号运算符) , new , delete , new[] , delete[] , ->*
注意:
重载运算符函数可以对运算符作出新的解释,但原有基本语义不变:
不改变运算符的优先级
不改变运算符的结合性
不改变运算符所需要的操作数个数。
只能重载C++语言中已有的运算符,不能创建新的运算符。
经重载的运算符,其操作数中至少应该有一个是自定义类型。
用友元函数重载运算符
运算符重载为类的友元函数, 如果需要重载一个运算符,使之能够用于操作某类对象的私有成员,可以此将运算符重载为该类的友元函数。
函数的形参代表依自左至右次序排列的各操作数。
友元函数没有 this 指针,所需操作数都必须在参数表显式声明,很容易实现类型的隐式转换
C++中不能用友元函数重载的运算符有 = () [] ->
例 复数运算
#include<iostream>
using namespace std;
class Complex
{ public:
Complex( double r =0, double i =0 ) { Real = r ; Imag = i ; }
Complex(int a) { Real = a ; Imag = 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, Imag ; };例 复数运算
Complex operator + ( const Complex & c1, const Complex & c2 )
{
double r = c1.Real + c2.Real ; double i = c1.Imag+c2.Imag ;
return Complex ( r, i ) ;
}
Complex operator - ( const Complex & c1, const Complex & c2 )
{
double r = c1.Real - c2.Real ; double i = c1.Imag - c2.Imag ;
return Complex ( r, i ) ;
}
Complex operator- ( const Complex & c )
{ return Complex ( -c.Real, - c.Imag ) ; }
void Complex :: print() const
{ cout << '(' << Real << " , " << Imag << ')' << endl ; }
//构造返回对象
int main()
{ Complex c1( 2.5,3.7 ), c2( 4.2, 6.5 ) ;
Complex c ;
c = c1 - c2 ; // operator-(c1,c2)
c.print() ;
c = 25 + c2 ;// operator+(25,c2)
c.print() ;
c = c2 + 25 ;// operator+(c2,52)
c.print() ;
c = - c1 ; // operator-(c1)
c.print() ; }
重载 ++ 与 –
设 A Aobject ;
运算符 ++和 – – 有两种方式:
前置方式: ++Aobject –Aobject
后置方式: Aobject ++ Aobject –
成员函数 重载 A :: A operator++ () ;
解释为: Aobject . operator ++( ) ;
友元函数 重载 friend A operator++ (A &) ;
解释为: operator ++( Aobject ) ;
成员函数 重载 A :: A operator++ (int) ;
解释为: Aobject . operator ++( 0 ) ;
友元函数 重载: friend A operator++ (A &, int) ;
解释为: operator++(Aobject, 0)
成员函数重载++
#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( ) ;
}