联编是指一个程序自身彼此关联的一个过程。按照联编所进行的阶段不同,可分为静态联编和动态联编两种。
静态联编
静态联编是指在程序编译连接阶段进行联编。这种联编又称为早期联编,这是因为这种联编工作是在程序运行之前完成的。
编译时所进行的联编又称为静态束定。束定是指确定所调用的函数与执行该函数代码之间的关系。
下面来看一个静态联编的程序例题:
<span style="font-size:18px;">#include <iostream> using namespace std; class Point { public: Point(double i,double j)//基类的构造函数 { x=i;y=j; } double Area() const//定义的常成员函数 { return 0.0; } private: double x,y; }; class Rectangle:public Point//公有继承的派生类 { public: Rectangle(double i,double j,double k,double l);//声明派生类的构造函数 double Area() const { return w*h; } private: double w,h; }; Rectangle::Rectangle(double i,double j,double k,double l):Point(i,j)//派生类构造函数的函数体 { w=k; h=l; } void fun(Point &s)//定义的类外函数 { cout<<s.Area()<<endl; } int main() { Rectangle rec(3.5,15.2,5.0,28.0);//定义的派生类的带参数的对象 fun(rec);//调用函数fun() }</span>
输出的结果为:0
程序分析:从输出的结果来看,该程序执行了Point::Area()的结果。派生类Rectangle的对象rec作为函数fun()的实参,而该函数的形参是类Point()的对象的引用s。在程序编译阶段,对象引用s所执行的Area()操作被联编到Point类的函数上。因此在执行函数fun()中的s.Area()操作时,返回值为0。
动态联编
动态联编是指在程序运行时进行的联编,这种联编又称为晚期联编。
动态联编要求在运行时解决程序中的函数调用与执行该函数代码间的关系,又称为动态束定。在上述的例题中,由于是静态联编,函数fun()中的参数s所引用的对象被联编到类Point上。那么实行动态联编,则s所引用的对象将被联编到类Rectangle上。由此可见,对于同一个对象的引用,采用不同的联编方式将会被联编到不同类的对象上,即不同联编可以选择不同的实现,这便是多态性。实际上是对于函数fun()的参数的多态性选择。联编是一种重要的多态性选择。
实现动态联编首先要有继承性,并且要求建立子类型关系,其次,一个重要的条件就是虚函数,继承是动态联编的基础,虚函数是动态联编的关键。
上述的例题可以改为:
<span style="font-size:18px;">#include <iostream> using namespace std; class Point { public: Point(double i,double j)//基类的构造函数 { x=i;y=j; } virtual double Area() const//定义的虚函数 { return 0.0; } private: double x,y; }; class Rectangle:public Point//公有继承的派生类 { public: Rectangle(double i,double j,double k,double l);//声明派生类的构造函数 virtual double Area() const//派生类的虚函数 { return w*h; } private: double w,h; }; Rectangle::Rectangle(double i,double j,double k,double l):Point(i,j)//派生类构造函数的函数体 { w=k; h=l; } void fun(Point &s)//定义的类外函数 { cout<<s.Area()<<endl; } int main() { Rectangle rec(3.5,15.2,5.0,28.0);//定义的派生类的带参数的对象 fun(rec);//调用函数fun() }</span>
输出的结果为:140.
程序分析:该程序中说明了虚函数,fun()函数的对象引用参数s被动态联编,该函数体内调用的Area()函数是在运行中确定的,而不是在编译时确定的,因此在运行时,实参rec为类rectangle的对象,于是Area()函数被确定为类Rectangle的Area()函数。
原文地址:http://blog.csdn.net/erlian1992/article/details/44262843