提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
一.运算符重载的方法
运算符重载:运算符重载的方法是定义一个重载运算符函数。格式如下:
函数类型 operator 运算符名称(形参表)
{对运算符的重载处理}
int operator+(int a,int b)
{return(a+b);}
例:用运算符重载使两复数相加
#include<iostream>
using namespace std;
class Complex
{
public:
Complex(){real=0;imag=0;}//定义构造函数
Complex(double r,double i){real=r;imag=i;}//构造函数重载
Complex operator+(Complex&c2);//声明重载运算符+的函数
void display();
private:
double real;//实部
double imag; //虚部
};
Complex Complex::operator+(Complex&c2)//定义重载运算符
{
Complex c;
c.real =real+c2.real;//两个复数实部相加
c.imag =real+c2.imag;//两个复数虚部相加
return c;
}
void Complex::display()
{
cout<<"("<<real<<","<<imag<<"i)"<<endl;输出 虚部形式
}
int main()
{
Complex c1(3,4),c2(5,10),c3;
c3=c1+c2;
cout<<"c1=";c1.display() ;
cout<<"c2=";c2.display() ;
cout<<"c1+c2=";c3.display() ;
return 0;
}
c1+c2解释为c1.operator+(c2)即以c2为实参调用c1的运算符重载函数operator+,进行两个复数相加。
上面的运算符重载函数可以更加简练:
Complex Complex::operator+(Complex&c2)
{return Complex (real+c2.real,imag+c2.imag);}
二.重载运算符的规则
- 不能重载的运算符:. \ * \ :: \ sizeof \ ?:
- 重载不能改变运算符运算对象的个数
- 不能改变运算符的优先级别
- 不能改变运算符的结合性
- 必须和用户自定义的自定义类型的对象一起使用,其参数至少有一个类对象或类对象的引用
三.运算符重载函数作为 类成员函数 和 友元函数
成员函数:
Complex Complex::operator+(Complex&c2)//定义重载运算符
{
Complex c;
c.real =real+c2.real;//两个复数实部相加
c.imag =real+c2.imag;//两个复数虚部相加
return c;
}
为什么只有一个参数呢:实际上有两个参数,由于重载函数是Complex类中的成员函数,因此有一个参数是隐含的,运算符函数是用this指针隐式的访问类对象的成员
友元函数:
{friend Complex operator+(Complex&c1,Complex&c2);
............};
Complex operator+(Complex&c1,Complex&c2)
{return Complex(c1.real+c2.real,c1.imag+c2.imag);}
运算符函数不作为成员函数,而是类外的普通的函数,在Complex类中声明它为友元函数。可以看到里面有两个参数。
二者区别:
- 运算符重载函数作为成员函数,它可以通过this指针自由地访问本类的数据成员,因此可以少写一个参数。
- 作为成员函数,要求第一个参数是一个类对象且与运算符类型相同
- 作为友元函数运算符左侧与函数第一个参数对应,右侧与第二个参数对应
四.重载双目运算符
**例:**重载运算符>
#include<iostream>
#include<cstring>
using namespace std;
class String
{
public:
String(){p=NULL;}
String(char*str);
friend bool operator>(String&string1,String&string2);//声明运算符为友元函数
void display();
private:
char* p; //字符型指针用于指向字符串
} ;
String::String(char*str)
{
p=str;
}
void String::display()
{
cout<<p;
}
bool operator>(String&string1,String&string2)//定义运算符重载
{
if(strcmp(string1.p,string2.p)>0)
return true;
else return false;
}
int main()
{
String string1("hello"),string2("book");
cout<<(string1>string2)<<endl;
return 0;
}
string对象以字符串“hello”作为实参,它的起始地址传递给构造函数的形参指针str,构造函数中,p指向hello
指导思想:先搭框架,逐步扩张,由简到繁,最后完善。边编程,边调试,边扩充;
五.重载单目运算
单目运算符只有一个操作符,因此函数只有一个参数。
例:每六十秒进一分钟
#include<iostream>
using namespace std;
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)//满60秒进一分钟
{sec-=60;
++minute;}
return*this;//返回当前对象值
}
int main()
{
Time timel(34,0);
for(int i=0;i<61;i++)
{
++timel;
timel.display() ;
}
return 0;
}
运行结果:共输出61行,到35:1
六.重载 流插入运算符"<<“和流提取运算符”>>"
">>"
重载函数形式:istream&operator>>(istream&,自定义类&);
ostream &operator>>(istream&output,Complex&c)
{output<<"(<<c.real<<"+"<<c.imag<<"i")"<<endl;
return output;}
只有在输出Complex类对象时才能用重载的运算符,对其他类型的对象无效。
"<<"
重载运算符:ostream&operator<<(ostream&,自定义类&);
七.不同类型数据间的转换
用 转换构造函数 进行不同类型数据的转换
回顾学习过的构造函数
默认构造函数 | Complex(); |
---|---|
用于初始化的构造函数 | Complex(double r,double i) ; |
用于复制对象的复制构造函数 | Complex(Complex&c); |
转换构造函数:Complex(double r){real=r;imag=0;}
只能有一个参数
上面的示例: 只有一个参数,作用是将double型的参数r转换成Complex类的对象,将r作为复数的实部。
类型转换函数
- 类型转换函数的作用是将一个类的对象转换成另一个类型的数据。
一般形式:operator 类型名()
{实现转换的语句}
在函数名前不能指定函数的类型,函数没有参数。类型转换函数只能作为成员函数,因为转换的主题是本类的对象。不能作为友函数或普通函数。
如果已经声明了Complex类
operator double()
{return real;)
函数返回double型变量real的值。
它的作用是将一个Complex类对象转换为一个double数据,
其值是Complex类中的数据成员real的值。
#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;
double imag;
} ;
int main()
{
Complex c1(3,4),c2(5,6),c3;
double d;d=2.5+c1;
cout<<d<<endl;
return 0;
}