封装性、继承性和多态性是面向对象设计的三大支柱。
C++语言支持两种多态性:编译时的多态性和运行时的多态性。
编译时的多态性通过使用重载来获得,运行时的多态性通过使用继承和虚函数获得。
重载包括函数重载和运算符重载。
一. 概述
1.定义
运算符重载是对已有的运算符赋予多重含义,同一个运算符作用域不用类型的数据导致不同的行为。
不能重载的运算符包括:"." "::" "?:" "*" "#"
2.规则
(1)除了少数几个以外,几乎全部可以重载,程序员不能定义新的运算符
(2)重载之后的优先级和结合性不变
(3)运算符重载是针对新类型数据的实际需要,对原有运算符进行适当的改造。一般来讲,重载的功能应当与原有功能类似,不能改变原运算符所需操作数的个数,同时至少要有一个操作数是自定义类型的操作数。
3. 运算符重载的形式
运算符重载可以使用成员函数和友元函数两种形式。
(1)只能使用成员函数重载的运算符有: =、()、[]、->、new、delete
(2)单目运算符最好重载为成员函数
(3)对于复合的赋值运算符,如+=、-=、*=、/=、&=、!=、~=、%=、>>=、<<=,建议重载为成员函数
(4)对于其他运算符,建议重载为友元函数
除了赋值运算符外,其他运算符函数都可以由派生类继承,并且派生类还可以选择的重载自己所需要的运算符(包括基类重载的运算符)。
运算符重载的实质就是函数重载。
二. 用成员函数重载运算符
将重载运算符的成员函数成为运算符函数。
在类定义体中声明运算符函数的形式为:
type operator @ (参数表)
type: 运算符函数的返回类型
operator: 运算符重载的关键字
@:所有重载的运算符符号
参数表中列的是该运算符所需要的操作数
若运算符是一元,则参数表为空,此时当前对象作为此运算符的单操作数;若运算符是二元的,则参数表中有一个操作数,此时当前对象作为此运算符的左操作数,参数表中的操作数作为此运算符的右操作数。
运算符函数的定义:
type 类名::operator@(参数表)
{
//运算符处理程序代码
}
例:
#include<iostream.h> class RMB { public: RMB(unsigned int d,unsigned int c); RMB operator+(RMB&); RMB operator++(); void display(){cout<<"yuan+jf/100.0"<<endl;} protected: unsigned int yuan; unsigned int jf; }; RMB::RMB(unsigned int d,unsigned int c) { yuan=d; jf=c; while(jf>=100){ yuan++; jf-=100; } } RMB RMB::operator +(RMB& s) { unsigned int c=jf+s.jf; unsigned int d=yuan+s.yuan; RMB result(d,c); return result; } RMB& RMB::operator++() { jf++; if(jf>=100){ jf-=100; yuan++; } return *this; //返回当前对象 } void main() { RMB d1(1,60);
RMB d2(2,50);
d3=d1+d2;RMB d3(0,0);
++d3;
d3.display;
}
三. 用友元函数重载运算符
在类定义中声明友元运算符函数的形式:
friend type operator @(参数表);
友元运算符函数的定义:
type operator@(参数表)
{
//运算符处理程序代码
}
友元函数不属于任何类,没有this指针,与成员函数完全不同。若运算符是一元的,则参数表中有一个操作数;若运算符是二元的,则参数表中有两个操作数。在用友元函数重载运算符时,所有操作数均需要参数来传递。友元运算符函数与成员运算符的主要区别在于其参数个数不同。当运算符的坐操作数是一个常数时,不能利用this指针,应当用友元函数重载。
例:
#include<iostream.h> class RMB { public: RMB(unsigned int d,unsigned int c); friend RMB operator +(RMB&,RMB&); friend RMB& operator ++(RMB&); void display(){cout<<(yuan+jf/100.0)<<endl;} protected: unsigned int yuan; unsigned int jf; }; RMB operator+(RMB& s1,RMB& s2) { unsigned int jf=s1.jf+s2.jf; unsigned int yuan=s1.yuan+s2.yuan; RMB result(yuan,jf); return result; } RMB& operator ++(RMB& s) { s.jf++; if(s.jf>=100) { s.jf-=100; s.yuan++; } return s; }
void main() { RMB d1(1,60);
RMB d2(2,50);d3=d1+d2;RMB d3(0,0);
++d3;
d3.display;
}