摘要】:本文阐述了静态联编和动态联编的概念和区别,通过具体实例分析了实现动态联编的条件,指出了虚函数是实现动态联编的基础。
【关键词】:静态联编;动态联编;虚函数
在C++中,联编是指一个计算机程序的不同部分彼此关联的过程。按照联编所进行的阶段不同,可分为两种不同的联编方法:静态联编和动态联编。
1.
静态联编
静态联编是指联编工作在编译阶段完成的,这种联编过程是在程序运行之前完成的,又称为早期联编。要实现静态联编,在编译阶段就必须确定程序中的操作调用(如函数调用)与执行该操作代码间的关系,确定这种关系称为束定,在编译时的束定称为静态束定。静态联编对函数的选择是基于指向对象的指针或者引用的类型。其优点是效率高,但灵活性差。
例1:静态联编
#include"iostream.h"
class A
{public:
voidf(){cout<<"A"<<"";}
};
classB:publicA
{public:
voidf(){cout<<"B"<<endl;}
};
Void main()
{A*pa=NULL;
Aa;Bb;
pa=&a;pa->f();
pa=&b;pa->f();
}
该程序的运行结果为:A A
从例1程序的运行结果可以看出,通过对象指针进行的普通成员函数的调用,仅仅与指针的类型有关,而与此刻指针正指向什么对象无关。要想实现当指针指向不同对象时执行不同的操作,就必须将基类中相应的成员函数定义为虚函数,进行动态联编。
2. 动态联编
动态联编是指联编在程序运行时动态地进行,根据当时的情况来确定调用哪个同名函数,实际上是在运行时虚函数的实现。这种联编又称为晚期联编,或动态束定。动态联编对成员函数的选择是基于对象的类型,针对不同的对象类型将做出不同的编译结果。C++中一般情况下的联编是静态联编,但是当涉及到多态性和虚函数时应该使用动态联编。动态联编的优点是灵活性强,但效率低。
动态联编规定,只能通过指向基类的指针或基类对象的引用来调用虚函数,其格式为:指向基类的指针变量名->虚函数名(实参表)或基类对象的引用名.虚函数名(实参表)
实现动态联编需要同时满足以下三个条件:
①
必须把动态联编的行为定义为类的虚函数。
②
类之间应满足子类型关系,通常表现为一个类从另一个类公有派生而来。
③
必须先使用基类指针指向子类型的对象,然后直接或者间接使用基类指针调用虚函数。
例2:动态联编
#include"iostream.h"
classA
{public:
Virtual voidf()//虚函数
{cout<<"A"<<"";}};
classB:publicA
{public:
Virtual voidf()//虚函数
{cout<<"B"<<endl;}
};
voidmain()
{ A*pa=NULL;
Aa;Bb;
pa=&a;
pa->f();
pa=&b;
pa->f();
}
该程序的运行结果为:A B
从例2程序的运行结果可以看出,将基类A中的函数f定义为虚函数后,当指针指向不同对象时执行了不同的操作,实现了动态联编。
3.
动态联编分析
动态联编要求派生类中的虚函数与基类中对应的虚函数具有相同的名称、相同的参数个数和相同的对应参数类型、返回值或者相同,或者都返回指针或引用,并且派生类虚函数所返回的指针或引用的基类型是基类中虚函数所返回的指针或引用的基类型的子类型。如果不满足这些条件,派生类中的虚函数将丢失其虚特性,在调用时进行静态联编。
例3:通过指向基类的指针来调用虚函数
#include"iostream.h"
Class base
{
public:
virtual void fun1(){cout<<"base fun1"<<endl;}
virtual void fun2(){cout<<"base fun2"<<endl;}
void fun3(){cout<<"base fun3"<<endl;}
void fun4(){cout<<"base fun4"<<endl;}
};
Class derived:public base
{public:
Virtual void fun1(){cout<<"derived fun1"<<endl;}
Virtual void fun2(intx){cout<<"derived fun2"<<endl;}
Virtual void fun3(){cout<<"derived fun3"<<endl;}
Void fun4(){cout<<"derived fun4"<<endl;}};
Void main()
{base*pb;
derivedd;
pb=&d;//通过指向基类的指针来调用虚函数pb->fun1();pb->fun2();pb->fun3();pb->fun4();}
该程序的运行结果:
Derived fun1 base fun2 base fun3 base fun4
本例中函数fun1在基类base和派生类derived中均使用了关键字virtual定义为虚函数,并且这两个虚函数具有相同的参数个数、参数类型和返回值类型。因此,当指针pb访问fun1函数时,采用的是动态联编。函数fun2在基类base和派生类de-rived中定义为虚函数,但这两个虚函数具有不同的参数个数。函数fun2丢失了其虚特性,在调用时进行静态联编。函数fun3在基类base中说明为一般函数,在派生类derived中定义为虚函数。在这种情况下,应该以基类中说明的成员函数的特性为标准,即函数fun3是一般成员函数,在调用时采用静态联编。函数fun4在基类base和派生类derived中均说明为一般函数,因此基类指针pb只能访问base中的成员。
例4:通过基类对象的引用来调用虚函数
#include"iostream.h"
Class CPoint
{public:
CPoint(doublei,doublej){x=i;y=j;}
Virtual double Area(){return 0.0;}
private:
doublex,y;
};
Class CRectangle:public CPoint
{public:
CRectangle(double i,double j,double
k,double l);
Double Area(){return w*h;}
private:
double w,h;
};
CRectangle::CRectangle(double i,double j,double
k,double l):CPoint(i,j)
{ w=k;h=l; }
Void fun(CPoint &s)
{ cout<<s.Area()<<endl; }//通过基类对象的引用来调用虚函数
Void main()
{
CRectangle rec(3.0,5.2,15.0,25.0);
fun(rec);
}
该程序的运行结果为:375
例4中的成员函数Area在基类CPoint中使用了关键字virtual定义为虚函数,在派生类CRectangle中定义为一般函数,但是进行了动态联编,结果为15*25即375。这是因为一个虚函数无论被公有继承多少次,它仍然保持其虚特性。在派生类中重新定义虚函数时,关键字virtual可以写也可不写,但为了保持良好的编程风格,避免引起混乱时,应写上该关键字。
4.
小结
从以上四个例子中可以看出:虚函数是实现多态的基础,是实现动态联编的必要条件之一。动态联编要靠虚函数来实现,虚函数要靠动态联编的支持。两者相辅相成,缺一不可。
分享到:
相关推荐
C++虚函数与静态动态联编个人理解
c++ 静态联编和动态联编(代码举例,文字说明详细)(csdn)————程序
本文阐述了静态联编和动态联编的概念和区别,通过具体实例分析了实现动态联编的条件,指出了虚函数是实现动态联编的基础。
按照联编所进行的阶段不同,可分为两种不同的联编方法:静态联编和动态联编。 静态联编是指在编译阶段就将函数实现和函数调用关联起来,因此静态联编也叫早绑定,在编译阶段就必须了解所有的函数或模块执行所需要...
什么是多态性?请举例说明。...静态联编:在程序被编译时进行联编;(早联编)特点是程序执行快,但灵活性较小。 动态联编:在程序运行时联编。(晚联编,滞后联编)其特点是灵活性高,程序执行慢。
继承呼唤多态、虚函数、纯虚函数与抽象类、静态联编、动态联编
7.虚函数虚函数,实现虚函数支持的动态联编;功能:为一等学生发放奖金。,实现虚函数支持的动态联编;功能:为一等学生发放奖金。,实现虚函数支持的动态联编;功能:为一等学生发放奖金。,实现虚函数支持的动态联...
1.多态的概念与分类 多态(Polymorphisn)是面向对象程序设计(OOP)的一个重要特征。多态字面意思为多种状态。在面向对象语言中,一个接口,多种实现即为多态。...静态多态往往也被叫做静态联编。 动态多态则是指函数
编译时多态性:静态联编支持的多态性(静态多态性)——通过函数重载及运算符重载实现。 运行时多态性:动态联编支持的多态性(动态多态性)——通过虚函数实现。 四、函数重载 同一个类中的同名函数——参数个数...
第9章 多态性与虚函数 本章学习要求: 虚函数 多态性 静态与动态联编 9.1 多态性的概念 9.2 虚函数 9.3 静态绑定与动态绑定 9.4 纯虚函数和抽象类
13.5 在编译时的静态联编 13.6 在运行时的静态联编 13.7 在运行时的动态联编 13.8 在编译时的动态联编 13.9 调用虚函数 13.9.1 在虚函数中调用成员函数 13.9.2 3种调用虚函数的方式比较 13.10被继承的虚函数仍然是虚...
13.6 在运行时的静态联编 13.7 在运行时的动态联编 13.8 在编译时的动态联编 13.9 调用虚函数 13.9.1 在虚函数中调用成员函数 13.9.2 3种调用虚函数的方式比较 13.10被继承的虚函数仍然是虚函数 13.11系统是...
熟练掌握静态联编和动态联编的概念和用法 掌握纯虚函数和抽象类的概念和用法 实验内容 声明一个抽象类Shape,由它派生出3个类:Circle(圆),Rectangle(矩形)、Triangle(三角形),用函数分别输出以上三个图形的周长和...
- 第二节 虚函数与动态联编 - 第三节 抽象类 - 第四节 虚析构函数 - 第五节 设计继承 - 第六节 程序举例 - 本章小结 - 课后习题 ◇ 第十二章 输入输出流 - 课前索引 - 第一节 输入输出流类 - 第二节 ...
为什么说虚函数是C++最重要的特性之一呢,因为虚函数承载着C++中动态联编的作用,也即多态,可以让程序在运行时选择合适的成员函数。虚函数必须是类的非静态成员函数(且非构造函数),其访问权限是public。那么: ...
C++语言支持多态性,主要表现为支持[<函数重载和运算符重载>]、支持动态联编。 3. C++语言支持继承性,既支持单继承又支持[<多继承>]。 4. 类中成员的访问权限有3种,它们是:[<公有(public)>]、保护...
2. 了解类层次的设计方法,初步了解运算符重载、静态/动态联编及其在OOP中的应用等内容 1. 阅读附件中的VCAD程序的源代码,并将其编译、运行,简单地试验一下它的各项功能; 2. 分析VCAD程序的源代码中类层次的设计...
一、定义定义:在某基类中声明为...二、作用虚函数的作用是实现动态联编,也就是在程序的运行阶段动态地选择合适的成员函数,在定义了虚函数后,可以在基类的派生类中对虚函数重新定义,在派生类中重新定义的函数应与虚
在一个C++程序中,main函数的位置( c )。 (a) 必须在程序的开头 (b) 必须在程序的后面 ( c ) 可以在程序的任何地方 (d) 必须在其它函数中间 2.用C++语言编制的源程序要变为目标程序必须要经过( d )。 (a) ...