C++多态重难点

CSDN上已经有很多关于C++多态方面的一些系统介绍了,但是我看了一下一些有关于多态问题的细节问题文章较少,因此我想要出一片文章重点讲一讲我认为比较重点且容易被遗忘的知识点,一些比较基本的知识这里就不过多赘述了,可以参考其他优质博主的文章。

锁死多态的两个必要条件:

实现多态必须要实现虚函数的重写和指针or引用调用,这是人尽皆知的知识,但是在一些复杂一点考试题中,可能会把人给绕晕。

这一道考试题:

class A
{
public:
virtual void func(int val = 1){ std::cout<<“A->”<< val <<std::endl;}
virtual void test(){ func();}
};
class B : public A
{
public:
void func(int val=0){ std::cout<<“B->”<< val <<std::endl; }
};
int main(int argc ,char* argv[])
{
B*p = new B;
p->test();
return 0;
}

试着写一下运行结果是什么?你可能会写出B->0,当然也不排除别的情况,但是正确答案是B->1

具体原因见下图:
在这里插入图片描述

一定要牢记普通函数的继承是一种实现继承,而虚函数的继承是一种接口继承,{}以外的即函数接口,{}以内的即函数实现

改动一下题目,变成这样:

class A
{
public:
virtual void func(int val = 1){ std::cout<<“A->”<< val <<std::endl;}
};
class B : public A
{
public:
void func(int val=0){ std::cout<<“B->”<< val <<std::endl; }
virtual void test(){ func();}
};
int main(int argc ,char* argv[])
{
B*p = new B;
p->test();
return 0;
}

这样输出的结果就是B->0呢,此时test()已经不再是父类的成员函数,而是独属于子类,this指针自然变为B*类型,不满足多态的条件。

(这是一道笔试题,非常考察对多态条件判断的基本功)

不能virtual修饰的成员:

内联函数:
虚函数需要将函数地址存入虚表,而内联函数直接在调用出展开,是不存在地址的,也就没有对应能存入在虚表中指针变量。(但是部分编译器可能将内联函数识别为普通函数,使得virtual修饰不会报错)
(拷贝)构造函数:
指向虚表的指针在初始化列表中初始化的,无法在虚表指针未初始化之前在表中存放元素
静态成员函数:
.静态成员函数与具体对象无关,属于整个类,核心关键是没有隐藏的this指针,可以通过类名::成员函数名 直接调用,此时没有this无法拿到虚表,就无法实现多态,因此不能设置为虚函数

不要混淆虚表和虚基表:

虚基表是为了解决菱形继承造成的二义性问题,存放指针的偏移量(了解)
虚表是一个虚函数指针数组

虚表的一些细节:

1、父类和子类的虚表没有任何关系,二者虚表的地址不同,只不过在内容上可能相同(没有进行重写的时候)

在这里插入图片描述
在这里插入图片描述
/
/
/
/
/
/
2、地位均等的对象公用一张虚表
在这里插入图片描述
在这里插入图片描述

——————————————————————
再来看一道题目:

class A{
public:
A ():m_iVal(0){test();}
virtual void func() { std::cout<<m_iVal<<‘ ’;}
void test(){func();}
public:
int m_iVal;
};
class B : public A{
public:
B(){test();}
virtual void func(){
++m_iVal;
std::cout<<m_iVal<<‘ ’;}
};
int main(int argc ,char* argv[]){
A*p = new B;
p->test();
return 0;}

分析一下过程:
new B调用B的构造函数,会先调用父类的构造函数,此时虚表指针还未初始化,没有多态机制,仅仅普通调用A的构造函数,输出0;
而后再调用B构造函数的实现,再次调用test函数,此时虚表指针已经初始化,构成多态,因此输出1,同理输出2.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/384828.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

LabVIEW智能温度监控系统

LabVIEW智能温度监控系统 介绍了一个基于LabVIEW的智能温度监控系统&#xff0c;实现对工业环境中温度的实时监控与调控。通过集成传感器技术和LabVIEW软件平台&#xff0c;系统能够自动检测环境温度&#xff0c;及时响应温度变化&#xff0c;并通过图形用户界面(GUI)为用户提…

【51单片机】AT24C02(江科大、爱上半导体)

一、AT24C02 1.AT24C02介绍 AT24C02是一种可以实现掉电不丢失的存储器,可用于保存单片机运行时想要永久保存的数据信息 存储介质:E2PROM 通讯接口:12C总线 容量:256字节 2.引脚即应用电路 本开发板AT24C02原理图 12C地址全接地,即全为0 WE接地,没有写使能 SCL接P21 S…

Obsidian Publish的开源替代品Perlite

前几天就有网友跟我说&#xff0c;freenom 的免费域名不可用了&#xff0c;10 号的时候老苏进后台看了一下&#xff0c;还有一半的域名显示为 ACTIVE&#xff0c;似乎是以 2024年6月 为限。但到 11 号&#xff0c;老苏发现博客 (https://laosu.cf) 已经访问不了了&#xff0c;这…

使用SpringMVC实现功能

目录 一、计算器 1、前端页面 2、服务器处理请求 3、效果 二、用户登陆系统 1、前端页面 &#xff08;1&#xff09;登陆页面 &#xff08;2&#xff09;欢迎页面 2、前端页面发送请求--服务器处理请求 3、效果 三、留言板 1、前端页面 2、前端页面发送请求 &…

大话设计模式——1.模板方法模式(Template Method Pattern)

定义&#xff1a;定义一个操作中的算法的骨架&#xff0c;而将一些步骤延迟到子类中。模板方法使得子类可以不改变一个算法的结构即可重定义该算法的某些特定步骤 例子&#xff1a;比较重大的考试往往有A、B两套试卷&#xff0c;其中一套出现问题可以立马更换另一套。 定义基…

spring aop @annotation的用法

直接看原文: spring aop annotation的用法-CSDN博客 -------------------------------------------------------------------------------------------------------------------------------- annotation用在定义连接点时&#xff0c;对连接点进行限制。比如我们想对标注了…

百度PaddleOCR字符识别推理部署(C++)

1 环境 1.opencv&#xff08;https://sourceforge.net/projects/opencvlibrary/&#xff09; 2.cmake&#xff08;https://cmake.org/download/&#xff09; 3.vs2019&#xff08;(https://github.com/PaddlePaddle/PaddleOCR/tree/release/2.1) 4.paddleOCR项目-建议2.0(http…

Python网络通信

目录 基本的网络知识 TCP/IP IP地址 端口 HTTP/HTTPS HTTP HTTPS 搭建自己的Web服务器 urllib.request模块 发送GET请求 发送POST请求 JSON数据 JSON文档的结构 JSON数据的解码 下载图片示例 返回所有备忘录信息 此文章讲解如何通过Python访问互联网上的资源&a…

每日一练:LeeCode-617、合并二叉树【二叉树+DFS】

本文是力扣LeeCode-617、合并二叉树【二叉树DFS】 学习与理解过程&#xff0c;本文仅做学习之用&#xff0c;对本题感兴趣的小伙伴可以出门左拐LeeCode。 给你两棵二叉树&#xff1a; root1 和 root2 。 想象一下&#xff0c;当你将其中一棵覆盖到另一棵之上时&#xff0c;两…

15 ABC基于状态机的按键消抖原理与状态转移图

1. 基于状态机的按键消抖 1.1 什么是按键&#xff1f; 从按键结构图10-1可知&#xff0c;按键按下时&#xff0c;接点&#xff08;端子&#xff09;与导线接通&#xff0c;松开时&#xff0c;由于弹簧的反作用力&#xff0c;接点&#xff08;端子&#xff09;与导线断开。 从…

Photoshop 中的“彩蛋”

在 Photoshop 中隐藏了几个“彩蛋” Easter Eggs&#xff0c;是开发者留下的小秘密或玩笑功能&#xff0c;也许是他们在紧张的开发过程中的一种自我调节吧&#xff0c;就如复活节彩蛋一样&#xff0c;同样也可以给 Photoshop 的用户们带来一点小“惊喜”。 这些彩蛋通常以有趣的…

华为问界M9:全方位自动驾驶技术解决方案

华为问界M9的自动驾驶技术采用了多种方法来提高驾驶的便利性和安全性。以下是一些关键技术&#xff1a; 智能感知系统&#xff1a;问界M9配备了先进的传感器&#xff0c;包括高清摄像头、毫米波雷达、超声波雷达等&#xff0c;这些传感器可以实时监测车辆周围的环境&#xff0…

Ubuntu Desktop - Files Preferences

Ubuntu Desktop - Files Preferences 1. Behavior2. ViewsReferences 1. Behavior Go to file browser’s Menu -> Edit -> Preferences -> Behavior 2. Views Go to file browser’s Menu -> Edit -> Preferences -> Views ​​​ References [1] Yong…

使用 devc++ 开发 easyx 实现 Direct2D 交互

代码为 codebus 另一先生的 文案 EasyX 的三种绘图抗锯齿方法 - CodeBus 这里移植到 devc 移植操作如下&#xff1a; 调用dev 的链接库方式&#xff1a; project -> project option -> 如图所示 稍作修改的代码。 #include <graphics.h> #include <d2d1.…

Ubuntu Desktop - Disks

Ubuntu Desktop - Disks 1. Search your computer -> DisksReferences 1. Search your computer -> Disks ​ References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/

【好玩AI】【Prompt】快情人节了,用GPT写个【渣男模拟器】练习一下与女神的对话吧

情人节了&#xff0c;让我们用GPT写个【渣男模拟器】的机器人跟自己对话&#xff0c;来练习一下与女神的对话吧。 通过本文&#xff0c;你能学到&#xff1a; 1. 如何利用智谱清言平台零代码搭建一个自己的机器人Bot 通过本文&#xff0c;你还能学到&#xff1a; 怎么做一个渣男…

LeetCode:67.二进制求和

67. 二进制求和 - 力扣&#xff08;LeetCode&#xff09; 又是一道求和题&#xff0c;% / 在求和的用途了解了些&#xff0c; 目录 题目&#xff1a; 思路分析&#xff1a; 博主代码: 官方代码&#xff1a; 每日表情包&#xff1a; 题目&#xff1a; 思路分析&#xf…

《Linux 简易速速上手小册》第4章: 包管理与软件安装(2024 最新版)

文章目录 4.1 包管理基础4.1.1 重点基础知识4.1.2 重点案例&#xff1a;在 Ubuntu 上安装和管理软件4.1.3 拓展案例 1&#xff1a;添加软件仓库4.1.4 拓展案例 2&#xff1a;回滚软件到旧版本 4.2 使用 APT 与 YUM4.2.1 重点基础知识4.2.2 重点案例&#xff1a;在 Ubuntu 上配置…

MogaNet实战:使用 MogaNet实现图像分类任务(二)

文章目录 训练部分导入项目使用的库设置随机因子设置全局参数图像预处理与增强读取数据设置Loss设置模型设置优化器和学习率调整策略设置混合精度&#xff0c;DP多卡&#xff0c;EMA定义训练和验证函数训练函数验证函数调用训练和验证方法 运行以及结果查看测试完整的代码 在上…

「Linux」软件安装

MySQL5.7在CentOS安装 安装 配置yum仓库 更新密钥&#xff1a;rpm --import https://repo.mysql.com/RPM-GPG-KEY-mysql-2022安装MySQL yum库&#xff1a;rpm -Uvh http://repo.mysql.com//mysql57-community-release-el7-7.noarch.rpm使用yum安装MySQL&#xff1a;yum -y in…