??C++语言中有一些多义词,例如表示静态的关键字static,将static应用在变量、函数或类成员等不同场合,它所表达的含义不一样。源程序中相同的程序元素可能会具有不同的语法解释,C++语言称这些程序元素具有多态性。C++语言有多种不同的多态形式,常见的有关键字多态、重载函数多态、运算符多态、对象多态和参数多态等。
??对具有多态性的程序元素作出最终明确的语法解释,这称为多态的实现。不同多态形式具有不同的实现时间点,编译时实现的多态称为编译多态,执行时实现的多态称为执行多态。
一、关键字多态和重载多态
1、关键字多态
??C++语言中的某些关键字时多义词,具有多态性,例如static
、const
、void
以及public/private/protetced
等。关键字多态是由编译器在编译源程序时根据上下文进行语法解释的,是一种编译多态。
2、重载函数多态
??编译时,由编译器根据调用语句中实参的个数和类型自动调用形参最匹配的那个重载函数。形态的函数名,调用时可能会调用不同的函数,这就是重载函数多态。重载函数多态是由编译器在编译源程序时实现的,也是一种编译多态。所谓实现重载函数多态,就是在编译时将调用语句中的函数名转换成对应重载函数的内存存储地址。将源程序中的函数名转换成某个具体的函数存储地址,这种函数名到存储地址的转换被称为是对函数的绑定。
二、运算符多态
??相同的运算符,计算机会根据数据类型来选择执行不同的运算,这就是运算符的多态性。运算符多态是由编译器在编译时进行语法解释的,是一种编译多态。
??通过一个复数的示例来更好的理解运算符多态,下面为复数类的代码:
class Complex
{
private:
double real,image; //实数的实部和虚部
public:
Complex(double x=0,double y=0) {real = x;image = y;} //构造函数
Complex(Complex &c) {real = c.real;image = c.image; } //拷贝构造函数
void Show() { cout << real <<"+"<< image <<"i"<<endl;} //显示复数
};
??重新定义C++语言已有运算符的运算规则,使同一运算符作用于不同数据类型数据时执行不同的运算,这就是运算符重载。正因为C++语言支持运算符多态,程序员才能重载运算符实现类运算。重载运算符就是以函数的形式来重新定义运算符的运算规则。其语法形式如下:
??函数类型 operator 运算符(形式参数)
??{ 函数体 }
??为类重载运算符,可以将运算符函数定义成类额成员函数,也可以定义成类外的一个友元函数。针对不同的运算符,其运算符函数的具体实现方法也有所不同,例如单目/双目、前置/后置等。
1、双目运算符“+”
??1)定义成类的成员函数
|
|
??如果不将运算符函数定义成类中的函数成员,那它就时类外的普通函数。为了让类外的运算符函数能访问类中的非公有成员,那就必须将它定义成类的友元函数。
??若运算符+被重载为复数类的函数成员,则调用形式为“c1.+c2”。其中c1为对象名,"."为成员运算符,"+"为函数成员名,c2为实参。
??若运算符+被重载为复数类的友元函数,则调用形式为“+(c1,c2)”。其中+为友元函数名,c1、c2均为实参。为了提高函数代码执行效率和数据保护,可以将函数成员的形参定义为常引用如Complex operator +(const Complex &c)
将形参c改为常引用。
??示例:
??Complex c1(1.3),c2(2,4),c3;
???? c3 = c1 + c2;c3.Show();//显示复数c3,显示结果:3+7i;
2、单目运算符 ++
??C++语言规定:前置单目运算符重载为函数成员时没有形参,而后置单目运算符时需要有一个int型形参。这个int型形参没有参数名,在函数体中并不使用,其目的纯粹是为了使这两个重名函数具有不同形参,这样才能重载。
class Complex //通过成员函数重载++运算符
{
private:
double real,image; //实数的实部和虚部
public:
Complex(double x=0,double y=0) {real = x;image = y;} //构造函数
Complex(Complex &c) {real = c.real;image = c.image; } //拷贝构造函数
void Show() { cout << real <<"+"<< image <<"i"<<endl;} //显示复数
Complex & operator ++() //实现前置++运算符的函数成员,