对C++多态学习的一点感受

对C++多态学习的一点感受
原创:郭萌 2002年9月3日

多态考虑的是类与类之间的层次关系以及类自身内部特定成员函数之间的关系问题,是解决功能和行为的再抽象问题。多态是指类中具有相似功能的不同函数是用同一个名称来实现,从而可以使用相同的调用方式来调用这些具有不同功能的同名函数。这也是人类思维方式的一种直接模拟,比如一个对象中有很多求两个数最大值的行为,虽然可以针对不同的数据类型,写很多不同名称的函数来实现,但事实上,它们的功能几乎完全相同。这时,就可以利用多态的特征,用统一的标识来完成这些功能。这样,就可以达到类的行为的再抽象,进而统一标识,减少程序中标识符的个数。

面向对象的多态性可以严格的分为四类:重载多态,强制多态,包含多态,和参数多态,前面两种统称为专用多态,而后面两种也称为通用多态。

包含多态是研究类族中定义于不同类中的同名成员函数的多态行为,主要是通过虚函数来实现。参数多态与类属(类模板)相关联,类属是一个可以参数化的模板,其中包含的操作所涉及的类型必须用类型参数实例化。这样,由类模板实例化的各类都具有相同的操作,而操作对象的类型却各不相同。

多态从实现的角度来讲可以划分为两类,编译时的多态和运行时的多态。前者是在编译的过程中确定了同名操作的具体操作对象,而后者则是在程序运行过程中才动态的确定操作所针对的具体对象。这种确定操作的具体对象的过程就是联编,也有的文献成为编联,束定或绑定。联编是指计算机程序自身彼此关联的过程,也就是把一个标识符名和一个存储地址联系在一起的过程;用面向对象的术语讲,就是把一条消息和一个对象的方法相结合的过程。按照联编进行的阶段的不同,可以分为两种不同的联编方法:静态联编和动态联编,这两种联编过程分别对应着多态的两种实现方式。

联编工作在编译连接阶段完成的情况成为静态联编。因为联编过程外程序开始执行之前进行的,因此有时也称为早期联编或前联编。在编译,连接过程中,系统就可以根据类型匹配等特征确定程序中操作调用与执行该操作代码的关系,其确定了某一个同名标识到底是要调用那一段程序代码。有些多态类型,其同名操作的具体对象能够在编译,连接阶段确定,通过静态联编解决,比如重载,强制和参数多态等。

和静态联编相对应,联编工作在程序运行阶段完成的情况称为动态联编,也称为晚期联编或后联编。在编译,连接过程中无法解决的联编问题,要等到程序开始运行之后再来确定,包含多态的操作对象的确定就是通过动态联编完成的。

下面我们们看看重载。

我们先看一个例子:

#include <iostream>
using namespace std;

class complex
{
public:
  complex(double r=0.0, double i=0.0) {real=r;imag=I;}
  complex operator +(complex c2); //运算符“+”重载成员函数
  complex operator -(complex c2); //运算符“+”重载成员函数
  void display();
private:
  double real;
  double imag;
};

complex complex::operator +(complex c2) //重载运算符函数实现
{
  complex c;
  c.real=c2.real+real;
  c.imag=c2.imag+imag;
  return complex(c.real,c.imag);
}

complex complex::operator –(complex c2) //重载运算符函数实现
{
  complex c;
  c.real=real-c2.real;
  c.imag=imag-c2.imag;
  return complex(c.real,c.imag);
}

void complex::display()
{
  cout<<real<<imag;<<endl;
}

void main()
{
  complex c1(5,4),c2(2,10),c3;
  cout<<"c1="; c1.display();
  cout<<"c2="; c2.display();
  c3=c1-c2; //使用重载函数符完成复数减法
  cout<<"c3-c2=";
  c3.display();
  c3=c1+c2; //使用重载函数符完成复数减法
  cout<<"c3+c2=";
  c3.display();
}

在本例中,我们把复数的加减法这样的运算重载为负数类的成员函数。可以看出,除了在函数声明及实现的时候使用了关键字operator之外,运算符重载成员函数与类的普通成员函数没有什么区别。在使用的时候,可以直接通过运算符,操作数的方式来完成函数调用,这时,运算符“+,-”原有的功能都不变,对整型数,浮点数等基本类型数据的运算仍然遵循C++预定义的规则,同时添加了新的针对复数运算的功能。“+”这个运算符,作用于不同的对象上,就会导致完全不同的操作行为,具有了更广泛的多态特征。

虚函数是动态联编的基础,属于包含多态类型。虚函数是非静态的成员函数,虚函数经过派生之后,在类族中就可以实现运行过程中的多态。

根据数值兼容性规则,可以使用派生来的对象代替基类对象。如果用基类类型的指针指向派生类,就可以通过这个指针访问到的之能是基类的同名成员;而如果将它设置为虚函数,则是用基类类型的指针就可以访问到该指针正在指向的派生类的同名函数。这样,通过基类类型的指针,就可以是属于不同派生类的不同对象产生不同的行为,从而实现了运行过程的多态。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值