琴弦上的熊

Machine should work, people should think...

  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  2 随笔 :: 1 文章 :: 1 评论 :: 0 Trackbacks
浅析对象模型及多态的内在实现
Dissecting The Object Model and the Internal Implementation of Polymorphism

文:蓝色feel
日期:2003年11月14日

概要:此文用简明扼要的语言解释了为什么多态是由指向对象的指针以及引用而不是对象本身来实现。

对象的理念以及对对象模型的思考(Basic concept of object and thinking in object model):

在面向对象的程序中。一个程序是由一些对象及其相互间的作用构成的。对象是被声明(declaration)的,其类型是确定的。所谓转型(type conversion)操作,本质上是对象拷贝的转型。举个简单例子,对于已声明变量 float var 而言,我们将其强制类型转换为 int ,此时,编译器先将 var 制作一份拷贝 var_tmp,再将 var_tmp 转化为 int 型,而 var 本身是不变的。

由此可见,对象是确定的,非多态的,其行为仅限于该对象所属数据类型的方法(function)(包括该类型基类的方法)。

由于对象的类型确定性,对象不能支持多态,所有有关对象的操作均是静态的(static)是能够事先认定的,是能够在编译期被计算及绑定的,因此对于一个已被声明的对象(declared object)而言,已丧失了执行期(运行时,run-time)的弹性。

多态的实现(Implementation of Polymorphism):

此程序设计典范(programming paradigm)在具体的程序中是由指针或引用这种对对象的间接操作所实现的。

为什么不能直接对对象应用多态,而是要通过指针或引用这种间接方式来应用呢?

一个对象,其大小在其被声明时已被确定(即是所有数据成员按32位对齐后的总和),如果非要对其应用多态,即非要让系统在运行期将其看作另一种类型(极有可能是基类或派生类)的对象,那么由于两种数据类型占据的内存字节数不同,或即使相同其解释方式不同,类型转换后,对象要么被切割,要么被扩充进一些垃圾字节(怎么变化要看目标类型对于源类型的字节数大小)此时的操作是不安全的。
然而对于一个指针而言,其大小是确定的(在32位的机器上均为一个32位的远指针)无论其指向什么类型的对象,其大小都是不变的。因此,指针从其本身特性上讲是类型灵活的,应用程序完全可以籍由操作系统的支持在执行期动态改变其指向的类型而不用担心指针会被切割或扩充。因此指针适合于用来从语言层面上实现多态。

引用对于编译器而言是通过指针来实现的,故在本质上与指针的行为并无不同

推论:

对于一个类体系,直接定义基类对象A,那么A的行为仅限于基类。但若定义该基类对象的指针或引用B,那么B的行为可扩展至该基类及其派生类

实例:

class BaseClass; // 声明基类
class DeriveClass; // 声明派生类

BaseClass ObjectEntity; // 声明基类对象A
BaseClass * pBaseObject = RetrieveData(); // 声明基类指针B
BaseClass & rBaseObject = * pBaseObject ; // 声明基类引用C

则A一定是基类对象,他的行为就被限定在基类中了。而B和C要么指向基类对象,要么指向其子类型(即派生类对象),他们既可以被基类方法,也可以被派生类的方法当做不同的类型来操作。
posted on 2006-07-26 19:09 琴弦上的熊 阅读(127) 评论(0)  编辑 收藏 引用

只有注册用户登录后才能发表评论。
网站导航: 博客园   IT新闻   BlogJava   知识库   博问   管理