静态联编、动态联编与虚函数

静态联编:在编译阶段 就将函数的实现与函数的调用绑定起来
动态联编:在程序运行时 将函数的实现与函数的调用绑定起来
例如:

#include<iostream>
using namespace std;
class base{
	public:print(){cout<<"this is base's print"<<endl;
	}
};
//派生类公有继承基类 
class derived:public base {
	public:print(){cout<<"this is drived's print"<<endl;
	} 
};

int main(){
	base b;
	b.print();//调用了base的print 
	derived d;
	d.print();// 调用了derived的print 
	base *p=&b;//p指向b 
	base &c=d;//c作为d 的引用 
	p->print();//调用了base的print 
	c.print();//调用了base的print 
}

执行结果为
执行结果在这里插入图片描述
这里采用了静态的联编从而d 的引用c在调用print函数时,由于自身为base类型,调用了基类的print

为了让c在调用时使用派生类的函数,则需要对print进行虚函数的声明。
如:`

class base{
public:virtual	print(){cout<<"this is base's print"<<endl;
	}
};
//派生类公有继承基类 
class derived:public base {
	public:print(){cout<<"this is drived's print"<<endl;
	} 
};

int main(){
	base b;
	b.print();//调用了base的print 
	derived d;
	d.print();// 调用了derived的print 
	base *p=&b;//p指向b 
	base &c=d;//c作为d 的引用 
	p->print();//调用了base的print 
	c.print();//调用了base的print 
}

结果为:
在这里插入图片描述
再来更好地理解虚函数的运行机制:其的实际执行步骤如下:
1.定义虚函数的时候编译器自动增加了一个指针vptr 指向该虚函数地址
2.若派生类未重写虚函数,其vptr指向基类虚函数,若重写则指向自身虚函数地址

注意:
1.派生类能继承虚函数,只要与基类虚函数同名,就无需声明,直接成为虚函数
2.对虚函数使用对象指针或者引用才是动态联编,当使用对象调用时为静态联编
3.虚函数是动态成员函数
4.如果将基类析构函数定义为虚函数,其所有派生类析构函数皆为虚函数,无论同名与否
5.不支持虚构造函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值