快速业务通道

解析动态联编(上篇)

作者 佚名技术 来源 程序设计 浏览 发布时间 2012-06-29

文章摘要

多态性是C++最主要的特征,多态性的实现得益于C++中的动 态联编技术。文章通过对动态联编的关键技术虚拟函数表进行深入的剖析,解析 的动态联编的过程极其技术要领。

关键字

多态性 动态联编 VTABLE 虚函数

文章正文

一 从多态性谈动态联编的必要性

在进入主题之前先介绍一下联编的概念。联编就是将模块或者函数合并在一起生 成可 执行代码的处理过程,同时对每个模块或者函数调用分配内存地址,并且对 外部访问也分配正确的内存地址。按照联编所进行的阶段不同,可分为两种不同 的联编方法:静态联编和动态联编。在编译阶段就将函数实现和函数调用关联起 来称之为静态联编,静态联编在编译阶段就必须了解所有的函数或模块执行所需 要检测的信息,它对函数的选择是基于指向对象的指针(或者引用)的类型。反 之在程序执行的时候才进行这种关联称之为动态联编,动态联编对成员函数的选 择不是基于指针或者引用,而是基于对象类型,不同的对象类型将做出不同的编 译结果。C语言中,所有的联编都是静态联编。C++中一般情况下联编也是静态联 编,但是一旦涉及到多态性和虚函数就必须使用动态联编。

多态性是面向 对象的核心,它的最主要的思想就是可以采用多种形式的能力,通过一个用户名 字或者用户接口完成不同的实现。通常多态性被简单的描述为"一个接口, 多个实现。在C++里面具体的表现为通过基类指针访问派生类的函数和方法。

下面我们看一个静态联编的例子,这种静态联编导致了我们不希望的结果 。

//1.cpp
1.#include <iostream.h>
2.class shape{
3.public:
4.void draw(){cout<<"I am shape"<<endl;}
5.void fun(){draw();}
6.};
7.class circle:public shape{
8.public:
9.void draw() {cout<<"I am circle"<<endl;}
10.};
11.main(){
12.class circle oneshape;
13.oneshape.fun();
14.}

程序的输出结果我们希望是"I am circle",但事实上 却输出了"I am shape"的结果,造成这个结果的原因是静态联编。静 态联编需要在编译时候就确定函数的实现,但事实上编译器在仅仅知道shape的地 址时候无法获取正确的调用函数,它所知道的仅是shape::draw(),最终结果只能 是draw操作束缚到shape类上。产生"I am shape"的结果就不足为奇了 。

为了能够引起动态联编,我们只需要将需要动态联编的函数声明为虚函 数即可。动态联编只对虚函数起作用。我们在通过基类而且只有通过基类访问派 生类的时候,只要这个基类中直接的或者间接(从上上层继承)的包含虚函数, 动态联编将自动唤醒。下面我们将上面的程序稍微改一下。

//2.cpp
1.#include <iostream.h>
2.class shape{
3.public:
4.virtual void draw(){cout<<"I am shape"<<endl;}
5.void fun(){draw();}
6.};
7.class circle:public shape{
8.public:
9.void draw() {cout<<"I am circle"<<endl;}
10.};
11.main(){
12.class circle oneshape;
13.fun (&oneshape);
14.}

程序执行得到了正确的结果"I am circle"。代码在VC6.0中执行。

到目前为止我们不清楚动态联编的 执行机制,但我们可以做个猜测。正如上面所说,对于函数的实际的对象类型不 同,联编结果也应该不同。在静态联编中,执行的困难在于无法通过基类知道需 要联编的子对象的确切类型。在1.cpp中shape的派生类既可能是circle,也可能是 其余的rectangle或者square等等,到底应该静态联编哪一个呢。迷惑正在于此。 动态联编在编译的时候应该也是不知道联编的确切对象类型的,(如果知道的话 就成了静态联编了),因此它只能通过一定的机制,使得

凌众科技专业提供服务器租用、服务器托管、企业邮局、虚拟主机等服务,公司网站:http://www.lingzhong.cn 为了给广大客户了解更多的技术信息,本技术文章收集来源于网络,凌众科技尊重文章作者的版权,如果有涉及你的版权有必要删除你的文章,请和我们联系。以上信息与文章正文是不可分割的一部分,如果您要转载本文章,请保留以上信息,谢谢!

分享到: 更多

Copyright ©1999-2011 厦门凌众科技有限公司 厦门优通互联科技开发有限公司 All rights reserved

地址(ADD):厦门软件园二期望海路63号701E(东南融通旁) 邮编(ZIP):361008

电话:0592-5908028 传真:0592-5908039 咨询信箱:web@lingzhong.cn 咨询OICQ:173723134

《中华人民共和国增值电信业务经营许可证》闽B2-20100024  ICP备案:闽ICP备05037997号