第十一讲:重载

重载


  1. 重载单目运算符
    单目运算符只有一个操作数(如 !a, -b, ++i, - -j 等),因此重载函数只有一个参数,如果重载函数为成员函数,还可以省约此参数。
    例:将“-”重载成友元函数。
    单目运算符一般重载为成员函数
#include <iostream.h> 
class complex 
{ private:
    double real,image; 
public:
   complex(double r=0,double i=0):real(r),image(i){};
   void show() 
   { cout<<real; 
     if (image>0)  cout<<'+'<<image<<'i'<<endl;
     else
         cout<<image<<'i'<<endl; }
     friend complex operator-(complex &com); 
};
complex operator-(complex &com) 
{ return complex(-com.real,-com.image); }
void main() 
{ complex ob1(1,-4.5),ob2;
   ob2=-ob1;
   ob2.show();
} 


例4.5: “++”重载成员函数。
对 Time类,模拟秒表,满60秒进一分钟,秒又从0开始计。输出分、秒。

#include <iostream.h>    // “++”重载
class Time
{public:
   Time(){minute=0;sec=0;}
   Time(int m,int s):minute(m),sec(s){}
   Time operator++();  // 重载++运算符
   void display(){cout<<minute<<":"<<sec<<endl;}
  private:
     int minute;   int sec; };
Time Time::operator++()
{  if(++sec>=60)
         {sec-=60;   ++minute;} 
    return *this;      // 返回当前对象值
}  
int  main()
{ Time time1(34,0);
   for (int i=0;i<65;i++)
          {++time1;     time1.display();}
 return 0; }

例4.6: 在4.5基础上增加后置自增运算符  “++”重载。
#include <iostream.h>
class Time
{public:
   Time(){minute=0;sec=0;}
   Time(int m,int s):minute(m),sec(s){}
   Time operator++();   //声明前置自增++重载函数
   Time operator++(int); //声明后置自增++重载
   void display()
       {cout<<minute<<":"<<sec<<endl;}
  private:   int minute, sec; 
};
区别:前置++ 是先自加,返回是修改后的对象本身。
          后置++ 是,返回是自加前对象,然后自加。
注意:后置++ 的int参数只是与前置++函数有所区别,没有任何作用。

Time Time::operator++()
{ if(++sec>=60)
  {sec-=60;   ++minute;} 
   return *this;}
Time Time::operator++(int)
{Time temp(*this);
        //保存当前对象 
sec++;
 if (sec>=60)  {sec-=60;   ++minute;} return temp;}   
int main()
{Time time1(34,59),time2;
 cout<<" time1 : "; time1.display();
 ++time1;
 cout<<"++time1: ";
 time1.display(); time2=time1++;
 cout<<"time1++: ";
 time1.display(); 
 cout<<" time2 : ";
 time2.display(); return 0;
}

2、 重载流插入和流提取运算符

C++的流插入运算符“<<”和流提取运算符“>>”是在类库中提供的。
cin是istream类的对象,cout是ostream 类的对象。
在类库提供的头文件中已经对“<<”和“>>”进行了重载(整型、实型等的输入和输出)。
凡是用 cout<< 和 cin>> 进行输入输出的,都要将:
#include

include


#include <iostream.h>
class complex
{public:
   friend ostream & operator << (ostream&, complex&);
   friend istream & operator >> (istream&, complex&);
private:  double real, image;
} ;
ostream& operator << (ostream& output, complex& c)
{output<<"("<<c.real<<"+" <<c.image<<"i)"<<endl;  
 return output;  }
istream& operator >> (istream& input, complex& c)
{cout<<" 请输入复数的实数部分和虚数部分 "<<endl;
 input>>c.real>>c. image;
 return input;  }
void main( )
{ complex c1, c2; //定义复数对象 
   cin>>c1>>c2;        // 使用本程序重载定义的功能
  cout<<"c1="<<c1<<endl; // 使用本程序重载定义的功能
  cout<<"c2="<<c2<<endl;
}

3、 不同类型数据间的转换

A、标准类型数据间的转换
1)C++支持不同类型数据间的自动转换。— 隐式转换
例如:int i = 6;
i = 7.5 + i;
求解表达式时,编译系统先将整数6转换成double类型6.0,再与7.5相加,和为13.5,然后在赋给整数变量 i 之前,将13.5转换成整数13,并赋给变量 i 。

2) C++显式类型转换: 数据类型名 (数据)
注意:它与C语言格式不同,C语言是
(数据类型名) 数据
C++保留了C语言的格式,但提倡用C++的格式。
例如: int (13.6); // 结果等于13。

问题:用户自己定义的类对象能否转换成标准类型数据?一个类的对象能否转换成另外一个类的对象?
例如:复数类转换成整数或双精度数?
对于标准类型的转换,编译系统有规则,而对于用户自己声明的类型,就得让编译系统知道怎么进行转换。
构造函数:
默认构造函数:如complex ( );
用于初始化的构造函数:
如: complex (double r, double i)
B、转换构造函数:作用是将一个其它类型的数据转换成指定类的对象。
例如:
complex (double r) { real = r; image = 0; }
说明:作用是将double 型参数 r 转换成 complex 类的对象,将 r 作为复数的实部,虚部为0。
例如:已有转换构造函数:
complex (double r) { real = r; image = 0; }
则:complex c1(3.6);
// 建立c1对象,由于只有一个参数,调用转换构造函数
complex (13.6 );
// 建立无名对象,合法,但无法使用,此为类型转换
c1 = complex (13.6);
//合法,利用类型转换构造函数建立对象,并赋值给c1


#include <iostream.h> 
class complex 
{ private:    double real,image; 
public: 
   complex() { real = 0; image = 0; }                  // 普通构造函数
   complex(double r) { real = r; image = 0; }    // 转换构造函数
   void show() 
     { cout<<real; 
        if  (image>=0)  cout<<'+'<<image<<'i'<<endl;
        else  cout<<image<<'i'<<endl;  }
};
void main() 
{ complex c1(3.6);   // 调用转换构造函数
  c1.show();
  complex c2;   // 调用普通构造函数  
  c2.show(); 
  c2= complex (10.6); // 调用转换构造函数生成对象并赋值给c2.
  c2.show();
} 
         利用转换构造函数将指定数据类型转换成类对象的步骤如下:

①、声明一个类( 如complex );
②、在该类中定义一个转换构造函数(只有一个 参数),参数类型是待转换的类型。
③、以下形式进行类型转换:
类名(待转换类型的数据);
注意:转换构造函数只能有1个参数,若有多个参数则 不是转换构造函数。(多个参数转换哪个?)

C、类型转换函数—-类成员函数
类型转换函数的作用:将一个类的对象转换成另一类型的数据。省去了对不同的运算符一一重载的麻烦。
类型转换函数的格式:
operator 类型名( ) //将本类对象转换为指定类型
{ 实现转换的语句 }

例如:已经声明了一个complex类,可在类中定义类型转换函数:
   operator double( ) // double类型重载后除了原有含义,也有  
     { return  real; }   // 将complex对象转换成double类型的含义

注意:
1)类型转换函数使用operator关键字,因此也称为“类型转换运算符重载函数”。
2)类型转换函数只能是类成员函数,因为转换的主体是本类对象,不能作为友员函数或普通函数。

例4.9:类型转换函数的应用

#include <iostream>
using namespace std;
class Complex  //类定义
 {public:
   Complex(){real=0;imag=0;}
   Complex(double r,double i)
    {real=r;imag=i;}
   operator double()
                     //类型转换函数
     {return  real;}    
  private:
      double real, imag;
 };
int main()
{Complex c1(3,4),c2(5,-10),c3;
 double d;
 d=2.5+c1; //自动调用类型转换函数
 cout<<d<<endl;
 cout<<c1<<endl; 
     //自动调用类型转换函数
 cout<<c2<<endl;
     //自动调用类型转换函数
  return 0;
}

3、不同类型数据间的转换

    转换构造函数和类型转换函数有一个共同的特点:在需要的时候,系统会自动调用这些函数。
例如:若已定义double变量到 d1、d2,complex对象  c1,c2。且类中已定义了类型转换函数,设程序有以下表达式:
            d1 = d2 + c1
    编译系统发现“+”左侧的d2是double型,右侧c1是  complex对象,如果没有对“+”重载,就会检测有无类型转换函数,结果发现对double的重载函数,就调用该函数,将complex对象c1转换成double型数据,建立了一个临时的double型变量,并与d2相加,最后将double 型和数赋给变量d1。

例4.10 运算符重载、转换构造函数的综合应用


#include <iostream.h>
class complex
{public:
   complex( ){ real=0; image=0; }
   complex (double r)//转换构造函数
   { real=r; image=0; }
   complex (double r, double i)
   { real = r; image = i; }
   friend complex operator +
     (complex c1,complex c2);
  operator double(){return real;}
// 此时 类型转换函数会产生二义性.
   void display( );
private:
   double real, image;
};
void complex::display( )
{ cout<<"("<<real<<","
          <<image<<"i)"<<endl;
}
complex operator +(complex c1,
                                   complex c2)
{ // 运算符重载为友元
  return complex (c1.real+c2.real,
                               c1.image+c2.image);
}
void  main( )
{ complex c1(3,4), c2(5,-10), c3;
  c3 = c1+ 2.5;   // 
 c3.display( );
}

3、 不同类型数据间的转换
程序分析:
1)如果没有定义转换构造函数,程序出错,因为即使重载运算符,也不能让complex对象与double数据相加。
2)定义了转换构造函数,也重载了“+”运算符,在处理c1+2.5时,编译系统解释为operator +(c1, 2.5),由于2.5不是complex 对象,系统先调用转换构造函数 complex(2.5),建立一个临时对象,其值为( 2.5 +0i )。表达式成为:
operator + (c1,complex(2.5))
// 两对象相加,结果赋给c3。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值