其实在学习的时候,一直没有搞懂为什么要用虚函数,为什么需要传递基类的引用或者指针,要用谁的时候写谁不就好了。其实这时候我的思维还局限在面向过程编程,不是面向对象编程。现在搞明白了,因为多态,利用继承的思想,减少代码复用。我们来看下面的例子。
#include<iostream> using namespace std; // 基类Fish class Fish{ public: // virtual void Swim(){ void Swim(){ cout << "Fish Swim." << endl; } virtual void Sleep(){ cout << "Fish Sleep." << endl; } }; // 派生类Tuna class Tuna:public Fish{ public: void Swim(){ cout << "Tuna Swim." << endl; } void Sleep(){ cout << "Tuna Sleep." << endl; } }; // 派生类Carp class Carp:public Fish{ public: void Swim(){ cout << "Carp Swim." << endl; } void Sleep(){ cout << "Carp sleep." << endl; } }; // 有一个函数,接受Fish类型的参数,调用sleep函数 // 我们直接创建想要的对象,就行调用就行 // 比如说,我们想要Tuna和Carp显示sleep void SleepFish(Fish & fish){ fish.Sleep(); } // 如果为每个派生类都建立一个函数 // 会非常的繁琐,比如说swimfish // 如果直接调用派生类对象, // 那么每次添加新的派生类时,都需要修改代码来处理新的类。 // 而使用虚函数,只需要在新的派生类中重写虚函数即可。 void SwimFish(Tuna & fish){ fish.Swim(); } int main(){ Tuna mydinner;
//直接调用sleepfish SleepFish(mydinner);
//swimfish就需要为每个派生类对象创建不同的函数 SwimFish(mydinner); // 直接调用sleepfish Carp mylunch; SleepFish(mylunch); return 0; }
代码中所写,我们在基类中将Sleep()设置为虚函数,在派生类中重写Sleep()。 当我们实例化一个Tuna的对象mydinner时,在函数SleepFish传入对象mydinner,在函数中调用Sleep,会显示“Tuna sleep.”。同理,实例化一个Carp对象mylunch,会显示“Carp sleep.”。在Swim()中,假如我们想在函数SleepFish中调用不同对象的Swim,就需要创建不同的SwimFish,比较繁琐。也是正因为如此,多态的思想体现了出来,允许不同类的对象对同一消息做出响应的能力,即同一个函数调用可以有不同的行为。
关于多态的总结:
多态主要有两种形式: 1.编译时多态(早期绑定):这种多态通过函数重载(Overloading)和方法重写(Overriding)实现。函数重载发生在同一个类中,当有多个同名函数但参数列表不同时。方法重写发生在继承关系中,子类重写父类的方法,但保持相同的方法签名(方法名、参数列表和返回类型)。 2.运行时多态(晚期绑定):这种多态主要通过虚函数(Virtual Functions)实现。当一个基类的指针或引用指向派生类的对象,并调用一个虚函数时,将根据对象的实际类型来确定调用哪个函数。这通常涉及到动态绑定(Dynamic Binding),即在程序运行时确定方法的调用。标签:Swim,调用,函数,多态,C++,SleepFish,基类 From: https://www.cnblogs.com/qhj384343045-/p/18378843