运算符重载


7.1 运算符重载规则
7.1.1 重载运算符的限制
重载运算符函数可以对运算符作出新的解释,但原有基本语
义不变:
①不改变运算符的优先级
②不改变运算符的结合性
③不改变运算符所需要的操作数
③不能创建新的运算符
7.1.2重载运算符的语法形式
运算符函数可以重载为成员函数或友元函数。
成员函数的语句格式:
类型  类名::operator  op(参数表)
{
   //相对于还定义的操作
}
其中,类名是函数的返回类型,类名是要重载该运算符的类。op表示要重载的运算符。函数名是operator op,由关键字operator和被重载的运算符op组成。参数表列出该运算符所需要的操作数。
用于类运算的运算符通常都要重载。但有两个运算符系统提供默认重载版本:
①赋值运算符"=",系统默认重载对象为对象数据成员的复制
②地址运算符"&",系统默认重载为返回任何对象的地址
当然也可以根据需要重载。
7.2 用成员或友元函数重载运算符
一元运算符:objectl  op  objectR
重载为成员函数,解释为:
Object . operator op ()
操作数由对象Object通过this指针隐含传递
重载为友元函数,解释为:
operator op (Object)
操作数由参数表的参数Object提供
二元运算符
objectl  op  objectR
重载为成员函数,解释为:
ObjectL . operator op ( ObjectR )
左操作数由ObjectL通过this指针传递,右操作数由参数
ObjectR传递
重载为友元函数,解释为:
operator op ( ObjectL, ObjectR )
左右操作数都由参数传递
1.成员运算符函数的原型在类的内部声明格式如下:
class X {
//…
返回类型 operator运算符(形参表);
//…
}
在类外定义成员运算符函数的格式如下:
返回类型 X::operator运算符(形参表)
{
函数体
}
2.双目运算符重载为成员函数
对双目运算符而言,成员运算符函数的形参表中仅有一
个参数,它作为运算符的右操作数,此时当前对象作为运
算符的左操作数,它是通过this指针隐含地传递给函数
的。
一般而言,如果在类X中采用成员函数重载双目运算符@,
成员运算符函数operator@ 所需的一个操作数由对象aa
通过this指针隐含地传递,它的另一个操作数bb在参数表
中显示,aa和bb是类X的两个对象,则以下两种函数调用方
法是等价的:
aa @ bb; // 隐式调用
aa.operator @(bb); // 显式调用
2.单目运算符重载为成员函数
对单目运算符而言,成员运算符函数的参数表
中没有参数,此时当前对象作为运算符的一个操
作数。
有一个Time类,包含数据成员minute(分)和sec(秒),模拟秒表,每次走一秒,满
60秒进一分钟,此时秒又从0开始算。要求输出分和秒的值。
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; //返回的是自加前的对象
}
一般而言,采用成员函数重载单目运算符时,以下两种方法是等价的:
@aa; // 隐式调用
aa.operator@(); // 显式调用
成员运算符函数operator @所需的一个操作数由对象aa通过this指针
隐含地传递。因此,在它的参数表中没有参数。
7.2.2 用友元函数重载
1.在第一个参数需要隐式转换的情形下,使用友元
函数重载
运算符是正确的选择
2.友元函数没有 this 指针,所需操作数都必须在参
数表显式
声明,很容易实现类型的隐式转换
3. C++中不能用友元函数重载的运算符有
= () [] ->
成员运算符函数与友元运算符函数的比较
(1) 成员运算符函数比友元运算符函数少带一个参数(后置的++、
--需要增加一个形参)。
(2) 双目运算符一般可以被重载为友元运算符函数或成员运算
符函数,但当操作数类型不相同时,必须使用友元函数。
7.3几个典型运算符的重载
设 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)
列:用友元函数重载++运算符。
设有简单类定义:
class  increase
{  public:
       increase();
       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;
}
他们的实现区别是,后置操作中使用了临时变量temp,保存对象a的原值,然后对a进行自增运算。
函数体中不应该使用伪参数,既a处不能写零,否则会引起调用的二义性。
7.3.2 重载赋值运算符
1.赋值运算符重载用于对象数据的复制
2.operator= 必须重载为成员函数
3.重载函数原型为:
类名 & 类名 :: operator= ( 类名 ) ;
7.3.3 重载运算符[]和()
①.运算符 [ ] 和 () 是二元运算符
②. [ ] 和 () 只能用成员函数重载,不能用友元函数重载
1.重载下标运算符 []
[  ]运算符用于访问的元素
重载格式类型 类 :: operator[] ( 类型 )
设x是类x的一个对象,则表达式
       x[y]
可被解释为x.operator[](y)
#include<iostream>
using namespace std;
class vector
{ public :
vector ( int n ) { v = new int [ n ] ; size = n ; }
~ vector ( ) { delete [ ] v ; size = 0 ; }
int & operator [ ] ( int i ) { return v [ i ] ; }
private :
int * v ; int size ;
};
int main ( )
{ vector a ( 5 ) ;
a [ 2 ] = 12 ;
cout << a [ 2 ] << endl ;
}
2.重载函数调用符 ()
()运算符用于函数调用
重载格式类型 类 :: operator() ( 参数表 ) ;
设 x 是类 X 的一个对象,则表达式
x ( arg1, arg2, … )
可被解释为
x . operator () (arg1, arg2, … )
列:
#include <iostream>
using namespace std ;
class F
{ public :
  double operator ( ) ( double x ,double y ) ;
} ;
double F :: operator ( ) ( double x ,double y )
{ return x * x + y * y ; }
int main ( )
{ F f ;
cout << f ( 5.2 , 2.5 ) << endl ;
}
7.3.4 重载流插入和流提取运算符
1.istream 和 ostream 是 C++ 的预定义流类
2.cin 是 istream 的对象,cout 是 ostream 的对象
3.运算符 << 由ostream 重载为插入操作,用于输出基本类型数据
4.运算符 >> 由 istream 重载为提取操作,用于输入基本类型数据
5.用友元函数重载 << 和 >> ,输出和输入用户自定义的数据类型
*重载输出运算符“<<”(只能被重载成友元函数,不能重载成成员函数)
定义输出运算符“<<”重载函数的一般格式如下:
ostream& operator<<(ostream& out,class_name& obj)
{
     out<<obj.item1;
     out<<obj.item2;
      .. .
     out<<obj.itemn;
     return out;
}
重载输入运算符“>>” (只能被重载成友元函数)
定义输入运算符函数 “>>”重载函数的一般格式如下:
istream& operator>>(istream& in,class_name& obj)
{
     in>>obj.item1;
     in>>obj.item2;
     . . .
     in>>obj.itemn;
     return in;
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值