首页 > 编程语言 >C++多态——虚函数

C++多态——虚函数

时间:2024-08-25 13:05:43浏览次数:9  
标签:Swim 调用 函数 多态 C++ SleepFish 基类

其实在学习的时候,一直没有搞懂为什么要用虚函数,为什么需要传递基类的引用或者指针,要用谁的时候写谁不就好了。其实这时候我的思维还局限在面向过程编程,不是面向对象编程。现在搞明白了,因为多态,利用继承的思想,减少代码复用。我们来看下面的例子。

#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

相关文章

  • 算法的学习笔记—包含 min 函数的栈(牛客JZ30)
    ......
  • 每天五分钟深度学习:从数学角度分析逻辑回归算法损失函数的来源
    本文重点前面的课程中,我们只得到了逻辑回归算法模型的损失函数(如下所示),但是你是否知道它为什么是逻辑回归算法的损失函数?本文对其进行拆分,从0到1构建该损失函数,从数学角度分析为什么它是逻辑回归的损失函数.逻辑回归在逻辑回归算法中,我们需要预测y^,也就是说目标函数如下所......
  • HTMLTestRunner_cn测试报告不显示案例的函数注释解决方法
    找到生成函数注释的代码如下:def_generate_report_test(self,rows,cid,tid,n,t,o,e):#e.g.'pt1.1','ft1.1',etchas_output=bool(oore)#ID修改点为下划线,支持Bootstrap折叠展开特效-Findyoutid=(n==0and'p�......
  • C++/python趣味实验之:互动游戏
    之前,我们已经使用python做出了可以根据C++数据变更的血条现在,拓展一下这个程序,制作一个可以互动的游戏既然是游戏,那就需要一个启动界面,所以我们可以制作一个蓝天白云的场景怎么实现呢?首先,我们要明白,这只是一个启动界面,所以一定是根据C++方面的数据而启动和关闭的,这时,就需要......
  • 在Kotlin中使用Spark SQL的UDF和UDAF函数
    1.项目结构与依赖1.1项目依赖使用gradle:在项目的build.gradle.kts添加dependencies{  implementation("org.apache.spark:spark-sql_2.12:3.3.1")}使用maven:在模块的pom.xml中添加<dependency><groupId>org.apache.spark</groupId>......
  • C++(asctime()、ctime())
    目录1.asctime()2.ctime()3.区别3.1示例对比4.总结在C++中,asctime()和ctime()都是用于将时间转换为可读字符串的函数,但它们有一些细微的区别。1.asctime()作用:asctime()函数将structtm类型的时间结构转换为字符串。这个函数通常与localtime()或gmtime()......
  • 部分数论函数结论的证明
    从莫比乌斯反演的文章里迁移出来的。部分数论函数结论的证明前面的小节中,我们使用了一些数论函数相关的结论,但并未给出证明。接下来我们来证明它们。欧拉函数证明\[\varphi(ij)=\dfrac{\varphi(i)\varphi(j)\gcd(i,j)}{\varphi(\gcd(i,j))}\]由欧拉函数公式,设\(x......
  • win10系统c++与opencv 依赖环境配置
    一、VSC++配置opencv库1、下载opencv(https://sourceforge.net/projects/opencvlibrary/files/opencv-win/3.3.0/)2、在官网下载opencv3.3.0.exe文件然后解压到D盘D:\opencv3、配置系统环境:①添加环境变量:控制面板-系统-高级系统设置-环境变量-系统变量Path中添加下......
  • C/C++语言基础--结构体知识详解(包括:结构体数组、字节对齐、位段等内容)
    本专栏目的更新C/C++的基础语法,包括C++的一些新特性前言C语言地结构体是核心内容之一,他运行自定义数据类型,可以将不同地数据类型当作成一个整体,变成一个数据类型,运用及其广泛欢迎点赞+收藏+关注,本人将会持续更新加粗样式文章目录结构体结构体是什么?结构体的申......
  • C++(std::cout 处理 char*)
    目录1.std::cout和char*2.std::cout处理nullptr情况3.数组与指针的区别4.特殊字符的处理5.总结在C++中,std::cout是标准输出流,通常用于将数据输出到控制台。在处理char*类型时,std::cout的行为与处理其他类型有所不同。1.std::cout和char*char*是一个指向字......