修改日期:2020/9/6
C++的虚函数
C++的虚函数的特点就是动态绑定,它的意思是动态绑定,在运行的时候,通过引用和指针,可以用基类的类,引用继承该c++类的派生类,虽然指针是基类,但实际上运行的是派生类的函数。
C++虚函数可以说是C++设计模式的基础了。
有一个问题是,有的时候在派生类中定义了一个函数,这个函数与基类中的虚函数的名字一样但是形参不一样,这说明两个不是一个函数呀,这个时候,编译器在动态绑定的时候会报错,他只会去找名字,却不会去对形参。这就让人很恼火。同时,如果虚函数没有覆写,程序员忘了,但编译器并不知道需要覆写。所以C++引入了一种新的思路,那就是override,这个东西能让编译器发现,如果这个函数没有覆盖,就会报错。当然如果不是虚函数,你还非要去覆盖,也会报错。如果是有override,它还会自动去匹配形参列表,如果不匹配,又是报错:你没有覆写。
当然。现在覆写,不意味着以后要覆写,因为虚函数派生类可以继承它。但有的时候,要防止后面的人对当前的虚函数进行覆写,那如果我们把一个东西定义为final,则之后的任何覆盖都是错误的。
虚析构函数
虚析构函数解决的问题是,因为类是动态绑定的,所以虚构的时候可能会出现 queue * a = Queue()的情况。(Queue是queue的派生。有可能派生类自己有一个指针,那总得释放吧。)
这个时候,虚析构函数不知道谁是谁,不知道该怎么析构,这个时候就需要提供一个覆写。
虚函数的生成,并不是不实现这个类了,而后面继承它的类,这个函数都是虚函数,但不一定要覆写。虚函数主要是为了动态绑定。在覆盖的过程中,形参啥的要一样,唯一可能的是,如果要返回的是自己的类型,那可以不一样。添加一个overide也可以表示这这是一个虚函数。
派生类的派生过程,是一个向下降维的过程。基类的指针和引用可以用派生类的东西。
这是因为派生类的集成,是基类和派生类的组合,可以想象那个经典的图,基类是一个基座部分,派生类是一个部分。派生类在处理基类的初始化的过程,是通过调用基类的构造函数来解决的。
纯虚函数
什么是抽象基类呢?是这个类中,有没有实现的函数,这个没有实现的函数就叫做纯虚函数。
纯虚函数的特点是什么呢?就是在其后面加上一个 = 0。
比如:double net_price(int ) = 0
虽然我们可以为net_price提供定义,但这个定义只能在类外提供,然后就算提供了,这个类也不能实现,这个类只有集成它的东西,对它进行覆写才能实现。
那么继承这个抽象基类的派生类,也可以不覆盖这个纯虚函数,但代价就是,它自己也是个抽象类,两个都不能实现,不能变成具体的对象。
那么为什么要实现这个东西呢?
因为有的时候,我们只是需要大家都实现一个相同的接口,提供相同的功能,但是,有可能这个类继承自上一个类,那么,上一个类的有些功能就仍然存在,这会造成,当前的对象也有使用这个功能的能力,可惜,我们根本不需要建立这个对象,这个对象只是中间的一环,甚至建立这个对象是有害的。所以要有个抽象基类。