Hello,C++(5)纯虚函数和抽象类

纯虚函数和抽象类

下面通过一个例子来说明纯虚函数的定义方法


在这个类当中,我们定义了一个普通的虚函数,并且也定义了一个纯虚函数。那么,纯虚函数是什么呢??从上面的定义可以看到,纯虚函数就是没有函数体,同时在定义的时候,其函数名后面要加上“= 0”。


纯虚函数的实现原理


本节从虚函数表的角度来说明纯虚函数的实现原理。

上面就是我们在前面课程讲到的多态的实现原理,在讲这一部分的时候,讲到了虚函数表以及虚函数表指针。如果我们定义了Shape这样的类,那么,Shape类当中,因为有虚函数和纯虚函数,所以,它一定有一个虚函数表,当然,也就一定有一个虚函数表指针。如果是一个普通的虚函数,那么,在虚函数表中,其函数指针就是一个有意义的值;如果是一个纯虚函数,那么,在虚函数表中,其函数指针的值就是0。通过对纯虚函数的讲解,大家也一定会发现:纯虚函数也一定是某个类的成员函数,那么,包含纯虚函数的类也叫作什么呢?我们把包含纯虚函数的类称之为抽象类。比如刚刚举的Shape类当中就含有一个计算周长的纯虚函数,那么,我们就说这个Shape类是一个抽象类。大家可以想一想,如果我们使用Shape这个类去实例化一个对象,那么这个对象实例化之后,如果想要去调用纯虚函数(比如要去调用这个计算周长的纯虚函数),那怎么去调用呢???我们说,显然是无法调用的。所以,我们得出一个结论:对于抽象类来说,C++是不允许它去实例化对象的。也就是说,抽象类无法实例化对象。那么,如果我们强行写成如下形式:


比如上面的,从栈中或者堆中去实例化一个对象,此时,如果我们去运行程序的话,计算机就会报错。而且,不仅如此,对于抽象类的子类也可以是抽象类。比如:我们如果定义一个Person的类如下:


因为人是要工作的,所以定义了一个work()函数,同时还定义了一个打印信息的函数。由于人比较抽象,所以也不知道工作要做啥,所以就定义work()为纯虚函数,同时,也不知道该打印啥信息,所以也定义成了纯虚函数。当我们使用Worker这个类去继承Person类的时候,我们可以想象一下,对于工人来说,其工种是非常多的,单单一个工人,我们倒是可以一些他的信息(比如:这个工人的名字,工号等等),但是,这个工人是什么工作,具体是做什么的,我们也没有办法清晰明了的描述出来,所以这个时候,我们可以也把它定义成一个纯虚函数(纯虚函数应用场景),如下所示。此时,这个Worker类作为Person的子类来说,它也是一个抽象类。

 
当我们明确了这个工人是什么工种(比如他是一名清洁工),清洁工这个类继承了Worker类(清洁工也是工人的一种),那么work()这个函数就有了一个明确的定义了(比如:他的工作就是扫地,我们可以将其打印出来),如下图所示。那么,此时,我们就可以使用清洁工(Dustman)这个类去实例化对象。


到此,我们需要强调说明一点的是:对于抽象类来说,它无法实例化对象,而对于抽象类的子类来说,只有把抽象类中的纯虚函数全部实现之后,那么这个子类才可以实例化对象。

小结:

抽象类不能被实例化,但可以被继承。只有把抽象类中所有的纯虚函数实现之后,才可以实例化对象

抽象类提供了一个统一的接口,从这里继承,虚函数只是声明在抽象类里并不实现。

面向抽象类编程思想强化

  • 虚函数和多态性使成员函数根据调用对象的类型产生不同的动作
  • 多态性特别适合于实现分层结构的软件系统,便于对问题抽象时   定义共性,实现时定义区别
  • 面向抽象类编程(面向接口编程)是项目开发中重要技能之一。


---------------------
参考:https://blog.csdn.net/yuanchunsi/article/details/78833899

猜你喜欢

转载自www.cnblogs.com/juanjuanduang/p/10847677.html
今日推荐