静态联编(函数重载)和动态联编(虚函数)

一、静态联编
定义:由于函数重载,编译器必须查看函数参数以及函数名就能确定使用哪个函数;这种C/C++编译器可以在编译过程中完成的联编,被称为静态联编
函数重载:在同一作用域中,可以有一组具有相同函数名,不同参数列表的函数,这组函数被称为重载函数

二、动态联编
定义:使用哪个函数是不能在编译时确定的,因为编译器不知道用户将要选择哪种类型的对象。所以,编译器必须生成能够在程序运行时选择正确的虚方法的代码,这就是动态联编。
1、虚函数
定义:定义非常简单,只需要在成员函数原型前加一个关键字virtual即可
特点:如果一个基类的成员函数定义为虚函数,那么它在派生类中也保持为虚函数;即使在派生类中省略了virtual关键字,也仍然是虚函数。
重定义的格式要求:
①与基类的虚函数有相同的参数个数
②与基类的虚函数有相同的参数类型
③与基类的虚函数有相同的返回类型

2、虚函数的访问
(1)对象名调用虚函数:和普通函数一样,虚函数一样可以通过对象名来调用,此时编译器采用的是静态联编。
通过对象名访问虚函数时,调用哪个类的函数取决于定义对象名的类型。
对象类型是基类时,就调用基类的函数;对象类型是子类时,就调用子类的函数
(2)指针访问:
①:使用指针访问非虚函数时,编译器根据指针本身的类型决定要调用哪个函数,而不是根据指针指向的对象类型
②:使用指针访问虚函数时,编译器根据指针所指对象的类型决定要调用哪个函数(动态联编),而与指针本身的类型无关
(3)引用访问:与指针类似;不同的是,引用一经声明后,引用变量本身无论如何改变,其调用的函数就不会再改变,始终指向其开始定义时的函数。
3、触发动态绑定的条件
(1)只有指定为虚函数的成员函数才能进行动态绑定,成员函数默认为非虚函数,非虚函数不进行动态绑定
(2)必须通过基类类型的引用或者指针进行函数调用
4、虚函数的工作原理
编译器处理虚函数的方法是:给每个对象添加一个隐藏成员。隐藏成员中保存了一个指向函数地址数组的指针。
这种数组称为虚函数表。虚函数表中存储了为类对象进行声明的虚函数的地址。
无论类中包含的虚函数是1个还是10个,都只需要在对象中添加1个地址成员(表的地址),只是表的大小不同而已
虚函数机制:
在这里插入图片描述
5、有关虚函数的注意事项
(1)构造函数:构造函数不能是虚函数
根据继承的性质,构造函数执行的顺序是:基类的构造函数->派生类的构造函数
但是如果基类的构造函数是虚函数,且派生类中也出了构造函数,
那么当下应该会只执行派生类的构造函数,不执行基类的构造函数,那么基类的构造函数就不能构造了
(2)析构函数:析构函数应当是虚函数,除非类不用做基函数。比如:假设Employee是基类,Singer是派生类,并添加一个char *成员,该成员指向由new分配的内存,然后,调用~Singer()析构函数来释放内存。
代码如下:

Employee * pe = new Singer;//true  Employee是Singer的基类
delete pe;//~Employee()or ~Singer()?

如果使用默认的静态联编,delete语句将会调用~Employee()析构函数。
这将释放Singer对象中的Employee部分指向的内存,但不会释放新的成员指向的内存。
但是如果析构函数是虚的,则上述代码将先调用Singer析构函数释放由Singer组件指向的内存,然后,调用Employee()析构函数来释放由Employee组件指向的内存。
最后,给类的析构函数定义析构函数没有错,即使这个类不做基类
(3)友员函数:友元函数不能是虚函数,因为友元不是类成员,而只有成员才能是虚函数
一个简单例子:

#include<iostream>
using namespace std;
class Base {
public:
	virtual void disp() {
		cout << "hello,base1" <<endl;
	}
	void disp2() {
		cout << "hello,base2" << endl;
	}
};
class Child1 :public Base {
public:
	void disp() {
		cout << "hello,child1" << endl;
	}
	void disp2() {
		cout << "hello,child2" << endl;
	}
};
void main(){
	Child1 child1;
	Base * base = &child1;
	base->disp();
	base->disp2();
	system("pause");
}

输出:hello,child1
hello,base2

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值