c++学习总结(多态性)

2023-05-16


在学习c++的过程中,根据自己的见解,把一些自己认为重要的、容易混淆的知识点记录下来,为了以后能够复习。今天主要总结多态性。主要从以下三个方面来讨论:what 、why 、how。

什么是多态性:

我们都知道多态性是为了实现接口的重用,我把它理解为"一个接口、多种方法",必须用virtual来实现多态。多态性作用于基类与子类之间,基类的函数定义为virtual函数,子类重写这个函数(此时子类的函数不需要显示指明为virtual).。

为什么使用多态:

对于这个问题,就要找多态性的优点了。多态能够实现接口的重用,也就是说命名了一个函数(函数名和参数都相同),但是函数体实现的功能各不相同,通过不同类的实例能够调用这个同名函数实现不同的功能,这也就实现了接口的重用。基类指针指向子类对象时,也能够调用子类的virtual函数,如果是调用子类的普通函数,那么还是实现基类自己的方法。

例子:

#include <iostream>
using namespace std;
/*定义一个基类*/
class Animal{
private:
char color; //颜色
int weight; //重量
public:
Animal(){}
void sleep()
{
cout<<"Animal want sleep"<<endl;
}
void virtual eat() // 虚函数
{
cout<<" Animal want eat meat"<<endl;
} 
};
class Dog : public Animal{
private:
char category;  //动物分类(家禽类...)
public:
Dog(){}
void sleep()
{
cout<<"Dog want sleep"<<endl;
}
void eat()
{ 
cout<<"Dog want eat meat"<<endl;
}
};
int main()
{
Dog dog;
Animal *p = &dog;
p->sleep();
p->eat();
}


这个例子的输出结果是:Animal want sleep

        Dog want eat meat

p->sleep() 调用的是Animal类的sleep方法,因为*p 虽然指向的是子类的对象,但是它本身是基类的实例,还是应该调用基类的方法。p->eat()调用的是子类的eat()方法,这里涉及到的是动态绑定。p->sleep()在预编译的时候就已经确定了调用哪个函数,即静态绑定;而p->eat() 是在执行的时候才确定具体调用哪个函数,即动态绑定。对于多态的问题,这时候在类中创建了虚函数表,里面存放类的虚函数的地址,另外还生成了个vptr指针,指向这个虚函数表。

下面看一下调用机制,首先类Animal分配了内存空间,存放成员变量和成员函数。其中成员函数由类的所有对象共享,而成员变量则是每个对象独有。由于类中有virtual函数,所以在编译的时候,内存上生成了一个虚函数入口地址,里面存放虚函数表,表里面有虚函数地址,这个入口地址占4个字节。派生类中也有个虚函数表,它是对基类虚函数表进行一次复制,如果子类重写了基类的virtual函数,那么子类的虚函数表中对应的位置存放的就是子类自己定义的虚函数的地址。(不然存放的依然是基类的虚函数地址,即没有对基类的虚函数进行重写时,基类对象调用的还是基类的虚函数)。机制:当执行p->eat() ;判断Animal类的eat()为虚函数,访问p所指向的对象dog,在对象中得到Dog的虚函数表,然后在基类声明中找到eat()的位序(在这里就要用到vptr指针),访问子类的虚函数表的位序,得到eat()的函数地址。请大家多多指正。


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++学习总结(多态性) 的相关文章

  • 博客搬家

    博客搬家三次 xff0c 因CSDN原因 xff0c 一直失败 终于在上周搬家成功 博客新址 xff1a https www cnblogs com zhangxuechao 我真是无语了 xff0c 满屏的广告 xff0c 像看电影一样
  • netfilter

    通俗的说 xff0c netfilter的架构就是在整个网络流程的若干位置放置了一些检测点 xff08 HOOK xff09 xff0c 而在每个检测点上登记了一些处理函数进行处理 xff08 如包过滤 xff0c NAT等 xff0c 甚
  • Linux挂载Windows文件夹

    sudo mount t cifs o user 61 username Windows用户名 o uid 61 myname password 61 pass Linux用户名 密码 o gid 61 users o defaults m
  • 单幅图像场景理解,论文解读

    Karsch K Liu C Kang S B Depth Transfer Depth Extraction from Video Using Non Parametric Sampling J IEEE Transactions on
  • AD转换 XPT2046

    首先介绍一下csdn屏蔽广告 这个至关重要 xff0c 请参考 https blog csdn net Demo Liu article details 81538222 应用电路 引脚功能描述 控制位命令 控制字节各位描述 单端模式输入配
  • Windows VNC远程连接用法

    VNC Virtual Network Console 是虚拟网络控制台 被控端 被控端需要打开服务 xff0c 等待主控端连接 服务端已经启动成功 xff0c 右下角有小图标 主控端 打开主控端 xff0c 连接被控端 输入被控端ip 输
  • Cheat Engine 基本用法

    首先介绍一下csdn屏蔽广告 这个至关重要 xff0c 请参考 https blog csdn net Demo Liu article details 81538222 打开游戏 当前血量2620 打开Cheat Engine 扫描262
  • SPL06-001 气压计

    歌尔是全球领先的MEMS厂家 xff0c 最新推出新款气压传感器SPL06 001 xff0c 定位精度可达5cm 手册地址 https download csdn net download zhangxuechao 10548473 寄存
  • 易语言网页登录 POST

    首先介绍一下csdn屏蔽广告 这个至关重要 xff0c 请参考 https blog csdn net Demo Liu article details 81538222 使用精易模块 打开网页登录窗口 抓取数据 输入用户名密码 xff0c
  • 十六进制字符串转换为十进制

    十进制字符串转换为十进制数 char str 61 34 123 34 int n 61 atoi str printf 34 d n 34 n 输出 xff1a 123 十六进制字符串转换为十进制数 法一 long long change
  • QTableWidget获取选中行内容

    首先介绍一下csdn屏蔽广告 这个至关重要 xff0c 请参考 https blog csdn net Demo Liu article details 81538222 QList lt QTableWidgetItem gt items
  • AT+CNUM获取不到手机号

    原因是卡商没有写入SIM卡 解决办法 手动写入 1 先确认SIM卡的本机号码 2 选择电话本存储 span class hljs comment AT 43 CPBS Select phonebook memory storage 34 O
  • linux远程桌面连接 VNC Server

    更新源 sudo apt get update 安装vnc4server sudo apt get install vnc4server 修改vnc远程连接密码 vncpasswd 编辑vnc4server的配置文件 vi vnc xsta
  • 上传gitee教程,Gitee怎么上传代码到仓库

    目录 第一步 xff1a 配置git的用户名和邮箱 第二步 xff1a 上传到远程仓库 第三步 xff1a 将仓库的master分支拉取过来和本地的当前分支进行合并 第四步 xff1a 将修改的所有代码添加到暂存区 第五步 xff1a 将缓
  • HJ6 质数因子

    描述 功能 输入一个正整数 xff0c 按照从小到大的顺序输出它的所有质因子 xff08 重复的也要列举 xff09 xff08 如180的质因子为2 2 3 3 5 xff09 输入描述 xff1a 输入一个整数 输出描述 xff1a 按
  • strstr字符串查找

    1 查找字符串 strstr是在字符串str1中查找是否含有字符串str2 如果有则返回字符串 xff0c 无则返回NULL 没有找到字符串 using namespace std include lt iostream gt includ
  • pip install cupy安装缓慢,安装cupy-cuda101 (for CUDA 10.1)代替

    直接安装cupy会特别的慢 xff0c 甚至以为卡死了 直接安装对应的cupy cuda包即可 cupy cuda101 for CUDA 10 1 cupy cuda100 for CUDA 10 0 cupy cuda92 for CU
  • WDS ISC-DHCP-SERVER PXE

    Debian Linux bullseye gt cat etc os release PRETTY NAME 61 34 Debian GNU Linux bullseye sid 34 NAME 61 34 Debian GNU Lin
  • [QT]QMessageBox 的四种用法

    http blog csdn net liukang325 article details 13768481 之前的一些QT笔记 xff0c 整理一下 cpp view plain copy print void MainWindow on
  • C语言宏定义技巧(常用宏定义)(转)

    写好C语言 xff0c 漂亮的宏定义很重要 xff0c 使用宏定义可以防止出错 xff0c 提高可移植性 xff0c 可读性 xff0c 方便性 等等 下面列举一些成熟软件中常用得宏定义 1 xff0c 防止一个头文件被重复包含 ifnde

随机推荐