多态性和虚函数

C++中有三大特性:抽象性,继承性,多态性,今天我们主讲多态性的使用。

多态性是指用一个名字定义不同的函数,这些函数执行不同但又类似的操作。多态性是指具有相似功能的不同函数使用的统一名称,从而使得相同的调用方式达到调用具有不同功能的同名函数的效用。也就是所谓的**“一个接口多个方法”**,
补充个概念:
静态联编和动态联编:

  1. 静态联编:在一个源程序经过编译连接成为可执行文件的这个过程中的编译阶段完成的,也就是说静态联编是在程序运行之前完成的;
  2. 动态联编:在程序运行时才动态完成的。
    静态联编在程序编译是就知道调用函数的全部信息,这种联编类型的函数调用速度快,效率高。
    编联是把一条消息和一个对象的方法相结合,这种结合是对象首先接收消息,然后把方法和消息结合在一起。

C++实现多态性有以下两种情况:
3. 编译时多态性:通过函数重载,运算符重载,模板实现
4. 运行时多态性:借助虚函数来实现。

虚函数

class shape
{
public:
	float area()
	{
		return -1;
	}
};
class circle :public shape
{
private:
	float radious;
public:
	 circle(float r)
	{
		 radious = r;
	}
	 float area()
	 {
		 return 3.14158*radious*radious;
	 }
};

我们来看这个求圆面积类,我们来看主函数

shape obj, *ptr;
	circle c(3.6);
	ptr = &obj;
	cout << ptr->area() << endl;
	ptr = &c;
	cout << ptr->area() << endl;

按理说是会出现 -1, 半径为3.6的圆的面积。但是
看结果在这里插入图片描述
为什么会出现这个情况呢?因为两次调用都是静态联编,所以都会调用到

float area()
	{
		return -1;
	}

我们只需要将这个函数改一下

virtual float area()
	{
		return -1;
	}

就能得到想要的答案了

通过这个例子我们可以看到,派生类中虚函数被重新定义实现不同的操作,这种被称为函数覆盖。

virtual 作用:
1:指示C++编译器对该函数的调用进行动态联编;
2:对象点运算符调用虚函数是静态联编过程
3:只有当访问虚函数是通过基类指针才获得运行时多态性
对于虚函数:
基类定义中必须把成员函数定义为虚函数
派生类中,虚函数被重新定义时,函数原型与基类中的函数原型必须完全相同
虚函数声明只出现在类声明的函数原型声明中,在派生类中可以以不显示的声明为虚函数
必须使用基类的指针(或者引用)访问虚函数,此时多态性才能实现
虚函数必须在继承体系下实现
虚函数必须是其所在类的成员函数
虚函数不能是友元函数
虚函数不能是静态成员函数
内联函数不能是虚函数,因为虚函数在类的内部定义,在编译时仍然看做是内联的
构造函数不能是虚函数但是析构函数可以是虚函数
一个虚函数无论被继承多少次仍保持虚函数特性

虚函数和重载函数的关系

重载函数要求函数有相同的函数名称,并有不同的参数序列;虚函数要求(函数名称,返回值参数序列)完全相同,具有完全相同的函数原型,
重载函数可以是成员函数和非成员函数,虚函数只能是成员函数
重载函数的调用那个是以所传递参数序列的差别(参数个数或者类型的不同)作为调用不同函数的依据,虚函数是根绝对象的不同调用不同类的虚函数。

纯虚函数和抽象类:
语法:
纯虚函数
virtual 函数类型 函数名称(形式参数表) = 0;
纯虚函数没有函数体,当声明为纯虚函数,基类就不给函数的实现部分,函数体由基类的派生类给出。
抽象类:
1:抽象类至少包含一个没有定义功能的纯虚函数,抽象类智能用作派生类的基类,不能建立抽象类;
2:抽象类不能用作参数类型,函数返回类型;
3:如果在抽象类的派生类没有重新说明纯虚函数,派生类只是继承基类的纯虚函数,这个派生类仍然是个抽象类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值