摘要】:本文阐述了静态联编和动态联编的概念和区别,通过具体实例分析了实现动态联编的条件,指出了虚函数是实现动态联编的基础。
【关键词】:静态联编;动态联编;虚函数
在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语言的主要特点...
C++虚函数与静态动态联编个人理解
根据联编发生的时机,可以分为静态联编(static binding)和动态联编(dynamic binding)。 **静态联编** 静态联编在编译期间就已经完成,即编译器在编译阶段就能确定函数的调用。这意味着,当一个函数通过指针或...
C++中的联编是编程过程中的一个...理解静态联编和动态联编以及它们在C++中的实现机制,对于编写高效、灵活的面向对象程序至关重要。正确使用虚函数和虚析构函数可以避免许多潜在的问题,尤其是在设计复杂类层次结构时。
按照联编所进行的阶段不同,可分为两种不同的联编方法:静态联编和动态联编。 静态联编是指在编译阶段就将函数实现和函数调用关联起来,因此静态联编也叫早绑定,在编译阶段就必须了解所有的函数或模块执行所需要...
在C++编程语言中,虚函数、多态和动态联编是面向对象编程的重要特性,它们使得程序设计更加灵活,能够实现抽象和代码复用。虚函数是实现多态的关键机制,它允许我们通过父类指针或引用调用子类重写的方法,从而达到...
多态性可以分为两种主要类型:静态联编(Static Binding)和动态联编(Dynamic Binding)。本讲解将深入探讨这两种联编方式,以及虚函数(Virtual Function)、纯虚函数(Pure Virtual Function)和虚析构函数...
### 动态联编与静态联编 #### 一、联编的概念 在计算机编程领域,特别是面向对象语言中,**联编**是指一个程序的不同部分如何被连接在一起的过程。根据联编发生的时机,可以将其分为两大类:静态联编和动态联编。 ...
C++支持两种联编方式:静态联编和动态联编。静态联编是在程序被编译时进行的,而动态联编是在程序运行时进行的。动态联编是C++实现运行时多态性的关键因素。 本文档还提供了一个示例程序,演示了如何使用虚函数来...
1. 动态联编与静态联编的区别在于,动态联编是在运行时确定调用的函数,而静态联编(也称为早期联编)则在编译时确定。动态联编需要通过指向对象的指针或对象引用来调用虚函数,或者在成员函数内部调用虚函数。 2. ...
1. 动态联编与虚函数的关系: - 动态联编通常在运行时执行,与编译时的静态联编相对。它是通过虚函数实现的。 - 虚函数是类中的非静态成员函数,它允许子类重写基类的行为。 - 没有虚函数,就不能实现基于对象...
1. 动态联编与虚函数: - 虚函数是动态联编的基础,它允许在运行时动态决定调用哪个函数。 - 动态联编不是在编译时确定操作函数,而是在运行时根据对象的实际类型确定。 - 为了实现动态联编,类之间需要满足子...
熟练掌握静态联编和动态联编的概念和用法 掌握纯虚函数和抽象类的概念和用法 实验内容 声明一个抽象类Shape,由它派生出3个类:Circle(圆),Rectangle(矩形)、Triangle(三角形),用函数分别输出以上三个图形的周长和...
静态联编在编译时就确定了函数调用与函数定义之间的关系,而动态联编则是在程序运行时才确定。 10. C++中的继承关系用父类和子类来描述。基类是指派生类的父类,而派生类是从基类继承而来的子类。 11. 函数模板是...
### 动态联编与虚函数 #### 静态联编 - 静态联编是指在程序编译连接阶段进行的联编,此时函数的绑定已经确定。 - 在静态联编中,函数调用的目标是在编译时确定的,因此无法实现多态。 #### 动态联编 - 动态联编是...
在构造函数或析构函数中调用虚函数,将采用静态联编。析构函数可以声明为虚函数,当基类的析构函数声明为虚函数时,无论派生类是否使用virtual关键字说明,派生类的析构函数一定是虚函数。 六、纯虚函数 纯虚函数...
- 联编是指程序模块之间互相调用的过程,分为静态联编和动态联编。静态联编在编译时完成,而动态联编在运行时确定。 - 多态性是C++的一个核心特性,允许不同对象对同一消息作出不同响应。多态分为编译时多态(通过...