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.

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AtCoder Beginner Contest 340(A-G)

A - Arithmetic Progression (atcoder.jp) 1.思路&#xff1a;循环输出即可 2.代码&#xff1a; #include <bits/stdc.h> #define rep(i,z,n) for(int i z;i < n; i) #define per(i,n,z) for(int i n;i > z; i--) #define PII pair<int,int> #define fi f…

2024年2月5日-2月11日周报

论文阅读 1. 本周计划2. 完成情况2.1 论文摘要2.2 网络结构2.3 损失函数2.4 优化器2.5 代码2.5.1 代码结果2.5.2 代码大致流程 4. 总结及收获4. 下周计划 1. 本周计划 阅读论文《Data-Driven Seismic Waveform Inversion: A Study on the Robustness and Generalization》并实…

TELNET 远程终端协议

远程终端协议 TELNET TELNET 是一个简单的远程终端协议&#xff0c;也是互联网的正式标准。 用户用 TELNET 就可在其所在地通过 TCP 连接注册&#xff08;即登录&#xff09;到远地的另一个主机上&#xff08;使用主机名或 IP 地址&#xff09;。 TELNET 能将用户的击键传到…

为什么总有人觉得前端很简单?尤其是水平半瓶水的人。

造成这个印象的原因很多&#xff0c;贝格前端工场结合自己的经验&#xff0c;为大家揭开这个谜底。低端的前端确实简单&#xff0c;但是高级阶段确实不简单。 缺乏深入了解&#xff1a; 有些人可能只是对前端开发有一些浅显的了解&#xff0c;没有深入研究过前端开发的技术和知…

T-Sql 也能更新修改查询JSON?

今天看见一个澳洲项目里面使用了 JSON_VALUE 这样的函数解析 JSON 我倍感诧异&#xff0c;我印象当中Sql Server并不支持JOSN的相关操作&#xff0c;他最多只把JSON当成一个字符串来存储&#xff0c;更不要说去解析&#xff0c;查询和更新了 我随后查询了下此函数&#xff0c;…

第三节 zookeeper基础应用与实战2

目录 1. Watch事件监听 1.1 一次性监听方式&#xff1a;Watcher 1.2 Curator事件监听机制 2. 事务&异步操作演示 2.1 事务演示 2.2 异步操作 3. Zookeeper权限控制 3.1 zk权限控制介绍 3.2 Scheme 权限模式 3.3 ID 授权对象 3.4 Permission权限类型 3.5 在控制台…

牛客周赛 Round 32 解题报告 | 珂学家 | 状压 + 前缀和异或map技巧

前言 整体评价 属于补题&#xff0c;大致看了下&#xff0c;题都很典。 欢迎关注 珂朵莉 牛客周赛专栏 珂朵莉 牛客小白月赛专栏 A. 小红的 01 背包 思路: 数学题 v, x, y list(map(int, input().split()))print (v // x * y)B. 小红的 dfs 思路: 枚举 其实横竖都有dfs…

Java编程练习之类的继承

1.创建银行卡类&#xff0c;并分别设计两个储蓄卡和信用卡子类。 import javax.swing.plaf.BorderUIResource;import java.util.Scanner;class Card {int Id; //银行卡&#xff1b;int password; //密码&#xff1b;double balance2000; //账户存款金额&#xff1b;String A…

软件安全测试报告如何编写?权威的安全测试报告如何获取?

软件安全测试报告是一份详尽的文件&#xff0c;它主要通过对软件进行全面、系统的测试&#xff0c;评估软件的安全性&#xff0c;并在测试结束后起草编写的报告。该报告能清晰地展示出软件的各项安全风险以及潜在威胁&#xff0c;为用户提供安全方面的决策依据&#xff0c;并帮…

指针的基本含义及其用法

1.前言 在学习C语言的时候&#xff0c;我们会经常接触一个概念&#xff0c;指针和地址&#xff0c;关于这两个概念很多人并不能理解地十分透彻&#xff0c;接下来我将详细介绍一下这两者的概念 2.地址 我们知道计算机的上CPU&#xff08;中央处理器&#xff09;在处理数据的时…

Java常用类与基础API--String的理解与不可变性

文章目录 一、字符串相关类之不可变字符序列&#xff1a;String&#xff08;1&#xff09;对String类的理解(以JDK8为例说明)1、环境2、类的声明3、内部声明的属性 &#xff08;2&#xff09;String的特性&#xff08;3&#xff09;字符串常量的存储位置1、举例2、String的存储…

1. pick gtk dll 程序的制作

文章目录 前言预览细节要点初始窗口尺寸提示音快速提示信息对话框AlertDialog鼠标移入移出事件布局与父子控件关系图片 后续源码及资源 前言 在之前的打包测试中我提到了需要一个挑选dll的程序于是我打算用Gtk来制作这个程序 预览 细节要点 初始窗口尺寸 只有主窗口有set_d…