C++之动态、静态联编

什么是联编?

联编,即绑定,就是将模块或者函数合并在一起生成可执行代码的过程,同时对每个模块或函数分配内存地址,并且对外部访问也分配正确的内存地址。

在编译阶段,实现联编的称为静态联编,又称早期联编;在运行阶段,实现的联编称为动态联编,又称晚期联编。在C++中一般是静态联编,但是重载、重写、虚函数的出现,要求动态联编的出现,因为编译器不知道用户将选择哪种类型的对象,执行具体哪一块代码。所以,编译器必须生成能够在程序运行时选择正确的虚函数的代码。即编译器对虚方法使用动态联编。

下面从一段代码中学习两者的区别:

静态联编

#include <iostream>
using namespace std;
class Point { //Point类表示平面上的点
double x,y; //坐标值
public:
Point(double x1=0, double y1=0) : x(x1),y(y1) { }//构造函数
double area() { return 0; }
};
class Circle: public Point { //Circle类表示圆
double r;//半径
public:
Ccircle(double x.double v.double r1 ):Point(x.v).r(r1) 
double area(){return 3.1415926*r*r}
};

int main( )
{ Point a(2.5,2.5); Circle c(2.5,2.5,1);//Point基类对象,Circle派生类对象
cout<<"Point area="<<a.area()<<endl; //基类对象,输出0
cout<<"Circle area="<<c.area( )<<endl;//派生类对象,输出3.14
Point *pc=&c , &rc=c;//基类指针、引用指向或引用派生类对象
cout<<"Circle area="<<pc->area( )<<endl;//静态联编基类调用,输出0
cout<<"Circle area="<<rc.area( )<<endl;1//静态联编基类调用,输出0
return 0;
}

动态联编:类多态

#include <iostream>
using namespace std;
class Point { //Point类表示平面上的点
double x,y; //坐标值
public:
Point(double x1=0, double y1=0) : x(x1),y(y1) { }//构造函数
virtual double area() {return 0; }//虚函数只能是类中的成员函数,不能是静态的,virtual必须在类体里面使用!
};
class Circle: public Point { //Circle类表示圆
double r;//半径
public:
Ccircle(double x.double v.double r1 ):Point(x.v).r(r1) 
double area(){return 3.1415926*r*r}
};//继承同名的虚函数(参数个数,参数类型,返回类型一致),在派生类中自动变成virtual,所以可写virtual也可不写

int main( )
{ Point a(2.5,2.5); Circle c(2.5,2.5,1);//Point基类对象,Circle派生类对象
cout<<"Point area="<<a.area()<<endl; //基类对象,输出0
cout<<"Circle area="<<c.area( )<<endl;//派生类对象,输出3.14
Point *pc=&c , &rc=c;//基类指针、引用指向或引用派生类对象
cout<<"Circle area="<<pc->area( )<<endl;//动态联编派生类调用,输出3.14
Point *pb=new Circle;
cout<<"Circle area="<<pb->area( )<<endl;//动态联编派生类调用,输出3.14
delete pb;
cout<<"Circle area="<<pc->Point::area( )<<endl;//强制使用静态联编,输出0
cout<<"Circle area="<<rc.area( )<<endl;1//动态联编派生类调用,输出3.14
return 0;
}

动态联编:类成员函数动态

#include <iostream>
using namespace std;
class Base {
public: virtual void print() {cout<<"Base "<<endl;}//虚函数};
};
class Derived: public Base {
public: void print() {cout<<"Derived" <<endl;}//虚函数};
void display (Base *p, void(Base::*pf)()){(p->*pf)();}
};//Base::*pf指向Base成员函数的指针
int main()
{
Derived d;Base b;
display(&d ,&Base::print); //输出Derived
display (&b ,&Base::print);//输出Base
return 0;
}

虚函数的调用规则是:根据当前对象,优先调用对象本身的虚成员函数。这和名字支配规律类似,不过虚函数是动态联编的,是在运行时(通过虚函数表中的函数地址)“间接"调用实际上欲联编的函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值