c++ 虚函数常见问题

1 虚函数,虚表基础

虚函数,虚表基础

2 虚函数表保存在哪里 ?

虚函数表在编译的时候确定。在 linux 下,保存在只读数据段的重定位段,这个段的名字是 .data.rel.ro。

如下代码,编译之后,使用 readelf -t a.out 可以查看看到这一段的大小是 0x68,如果从代码中删除一个虚函数,比如把函数 Do2() 不用 virtual 修饰,可以看到这个段的大小减小了 16。由此,可以验证虚函数表保存在了 .data.rel.ro。

#include <iostream>
#include <string>
#include <stdlib.h>
#include <stdio.h>class Base {
public:Base() {}~Base() {}virtual void Do1(int d) {std::cout << d << std::endl;}virtual void Do2(int d) {std::cout << d << std::endl;}
};class Derived : public  Base {
public:Derived() {}~Derived() {}virtual void Do1(int d) {std::cout << d << std::endl;}virtual void Do2(int d) {std::cout << d << std::endl;}
};int main() {Base *b = new Derived();b->Do1(1);b->Do2(2);delete b;return 0;
}

将 Base() 和 Derived() 中的函数 Do2() 不用 virtual 修饰,可以看到 .data.rel.ro 的大小减小了 16。

3 基类构造函数和析构函数中调用的虚函数是基类的还是派生类的 ?

基类构造函数和析构函数中调用的虚函数是基类的还是派生类的 ?

3 哪些函数不能声明为虚函数 ?

3.1 构造函数

构造函数声明为虚函数,编译错误如下。

访问虚函数首先要通过对象的地址找到虚函数表的地址,然后找到对应的虚函数来执行。也就是说虚函数的调用依赖于对象。而调用构造函数的时候,这个对象还不存在,所以构造函数不能声明为虚函数。

3.2 静态函数

静态函数声明为虚函数,编译错误如下。

与构造函数类似,静态函数中也没有 this 指针,所以静态函数不能声明为虚函数。

3.3 函数模板

函数模板不能声明为虚函数。编译报错如下。虚函数表需要在类定义的时候就要确定,对于函数模板来说,类定义的时候,这个函数有多少实例是不确定的,所以函数模板不能定义为虚函数。

#include <iostream>
#include <string>
#include <stdlib.h>
#include <stdio.h>class Base {
public:Base() {}~Base() {}template <class T>virtual void Do1(T d) {std::cout << d << std::endl;}void Do2(int d) {std::cout << d << std::endl;}
};int main() {Base *b = new Base();b->Do1(1);b->Do2(2);delete b;return 0;
}

函数模板不能声明为虚函数。但是类模板中的函数可以声明为虚函数,因为对于类模板来说,在定义一个实例的时候,这个类的定义就是确定的,虚函数表的大小也是确定的。

#include <iostream>
#include <string>
#include <stdlib.h>
#include <stdio.h>template <class T>
class Base {
public:Base() {}~Base() {}virtual void Do1(T d) {std::cout << d << std::endl;}void Do2(int d) {std::cout << d << std::endl;}
};int main() {Base<int> *b = new Base<int>();b->Do1(1);b->Do2(2);delete b;return 0;
}

4 inline 函数可以声明为虚虚函数

如下代码,Base 是基类,其中有一个 inline 虚函数 Do1()。Derived1 和 Derived2 是 Base 的派生类。分别创建 Base、Derived1、Derived2 的一个对象,然后通过指针调用函数 Do1()。代码编译没有问题,运行也没有问题。

#include <iostream>
#include <string>
#include <stdlib.h>
#include <stdio.h>class Base {
public:virtual ~Base() {}virtual inline void Do1(int d) {std::cout << d << std::endl;}
};class Derived1 : public Base{
public:virtual inline void Do1(int d) {std::cout << d << std::endl;}
};class Derived2 : public Base{
public:virtual inline void Do1(int d) {std::cout << d << std::endl;}
};void Do(Base *b, int data) {b->Do1(data);
}int main() {Base *b = new Base();Base *b1 = new Derived1();Base *b2 = new Derived2();Do(b, 10);Do(b1, 20);Do(b2, 30);return 0;
}

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

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

相关文章

仿《Q极速体育》NBACBA体育直播吧足球直播综合体育直播源码

码名称&#xff1a;仿《Q极速体育》NBACBA体育直播吧足球直播综合体育直播源码 开发环境&#xff1a;帝国cms7.5 空间支持&#xff1a;phpmysql 仿《Q极速体育》NBACBA体育直播吧足球直播综合体育直播源码自动采集 - 我爱模板网源码名称&#xff1a;仿《Q极速体育》NBACBA体育直…

网络攻防概述(基础概念)

文章目录 APTAPT概念APT攻击过程 网络空间与网络空间安全网络空间(Cyberspace)网络空间安全(Cyberspace Security) 网络安全属性机密性(Confidentiality或Security)完整性(Integrity)可用性&#xff08;Availability&#xff09;不可否认性&#xff08;Non-repudiation&#xf…

如何学习计算机网络(超详细,方法论)

分享一下学习计算机网络的方法论 首先是看视频&#xff1a; 这里我推荐中科大郑烇、杨坚全套《计算机网络&#xff08;自顶向下方法 第7版》课程 课程目标_哔哩哔哩_bilibili 教材采用神书《计算机网络&#xff08;自顶向下方法&#xff09;》&#xff0c;授课风格更偏向实…

企业如何正确地利用LLM大模型?

大型语言模型 (LLM) 不值得信任。就是这样。 考虑到它们先进的 AI 能力以及当今强大的基础模型的普遍知识&#xff0c;这似乎是一件令人惊讶的事情。然而&#xff0c;问题的关键在于 LLM 无法解释其输出。你不能信任 LLM 的结果&#xff0c;不是因为它不准确&#xff0c;而是因…

无畏并发: Rust Mutex的基本使用

并发是很多编程语言避不开的一块主要内容&#xff0c;主打一个无畏并发的Rust自然也面临这样的挑战。Rust中的Mutex提供了强大的同步原语&#xff0c;确保共享数据的线程安全&#xff0c;这篇文章中&#xff0c;我们会探讨Mutex的使用&#xff0c;从基础的用法到一些高阶内容。…

2024电工杯B题平衡膳食食谱的优化设计及评价原创论文分享

大家好&#xff0c;从昨天肝到现在&#xff0c;终于完成了2024电工杯数学建模B题的完整论文啦。 实在精力有限&#xff0c;具体的讲解大家可以去讲解视频&#xff1a; 给大家看一下目录吧&#xff1a; 目录 摘 要&#xff1a; 10 一、问题重述 14 二&#xff0e;问题分析 …

Python学习---基于HTTP的服务端基础框架搭建案例

整体功能&#xff1a; 1 创建框架构建相关的文件夹 2 创建app,模块文件 3 在 app模块文件中创建application函数(用于处理请求) 4 将request_handler()中的处理逻辑交由app模块的application函数完成 5 app模块的 application函数返回响应报文 6 在application 文件夹中创建一个…

淘工厂订单导出自动化工具

目录 下载安装与运行 主要目的 其他工具的弊端 本工具的优势 视频演示 下载新版后的注意事项 支持的导出项 什么叫一单多拍 常见问题 如何实现快捷登录 导出卡住时如何操作 如何精确导出 下载安装与运行 下载、安装与运行 语雀 主要目的 导出订单信息&#xf…

知识分享:隔多久查询一次网贷大数据信用报告比较好?

随着互联网金融的快速发展&#xff0c;越来越多的人开始接触和使用网络贷款。而在这个过程中&#xff0c;网贷大数据信用报告成为了评估借款人信用状况的重要依据。那么&#xff0c;隔多久查询一次网贷大数据信用报告比较好呢?接下来随小易大数据平台小编去看看吧。 首先&…

某钢铁企业数字化转型规划案例(114页PPT)

案例介绍&#xff1a; 该钢铁企业的数字化转型案例表明&#xff0c;数字化转型是钢铁企业应对市场竞争、提高生产效率、降低成本、优化资源配置和降低能耗排放的重要手段。通过引入先进的技术和管理理念&#xff0c;加强员工培训和人才引进&#xff0c;企业可以成功实现数字化…

欢乐钓鱼大师游戏攻略:自动钓鱼技巧!

《欢乐钓鱼大师》是一款极具趣味性和挑战性的钓鱼模拟游戏&#xff0c;为玩家提供了一个体验钓鱼乐趣的虚拟世界。从湖泊到河流&#xff0c;再到广袤的海洋&#xff0c;游戏中的各种钓场让人流连忘返。无论是新手钓友&#xff0c;还是经验丰富的老钓手&#xff0c;都可以在游戏…

k8s集群中pod的容器资源限制和三种探针

一、资源限制 总结&#xff1a; requests表示创建pod时预留的资源&#xff0c;limits表示pod能够使用资源的最大值。requests值可以被超&#xff0c;limits值不能超过&#xff0c;如果是内存使用超过limits会触发oom然后杀掉进程&#xff0c;如果是cpu超过limits会压缩cpu的使用…

20.SkyWalking

一.简介 SkyWalking用于应用性能监控、分布式链路跟踪、诊断&#xff1a; 参考连接如下&#xff1a; https://github.com/apache/skywalking https://skywalking.apache.org/docs/ 二.示例 通过官网连接进入下载页面&#xff1a;https://archive.apache.org/dist/skywalkin…

揭秘章子怡成功之路:她是如何征服世界的?

章子怡的演艺生涯可谓是一部传奇❗❗❗ 从一个普通工人家庭的女孩&#xff0c;到如今的国际巨星 她的每一步都充满了努力和汗水 她的舞蹈基础为她日后的演艺事业奠定了坚实的基础 而她对戏剧和电影的热爱更是让她在演艺道路上不断前行 从《我的父亲母亲》到《卧虎藏龙》&…

代码随想录|Day55|动态规划 part15|● 392.判断子序列 ● 115.不同的子序列

392.判断子序列 class Solution: def isSubsequence(self, s: str, t: str) -> bool: dp [[0] * (len(t) 1) for _ in range(len(s) 1)] for i in range(1, len(s) 1): for j in range(1, len(t) 1): if s[i - 1] t[j - 1]: dp[i][j] dp[i - 1][j - 1] 1 else: dp[i…

【UE5.1 角色练习】06-角色发射火球-part2

目录 效果 步骤 一、火球生命周期 二、添加可被伤害的NPC 三、添加冲量 在上一篇&#xff08;【UE5.1 角色练习】06-角色发射火球-part1&#xff09;基础上继续实现角色发射火球相关功能 效果 步骤 一、火球生命周期 为了防止火球没有命中任何物体而一直移动下去&#…

【全开源】赛事报名系统源码(Fastadmin+ThinkPHP和Uniapp)

基于FastadminThinkPHP和Uniapp开发的赛事报名系统&#xff0c;包含个人报名和团队报名、成绩查询、成绩证书等。 构建高效便捷的赛事参与平台 一、引言&#xff1a;赛事报名系统的重要性 在举办各类赛事时&#xff0c;一个高效便捷的报名系统对于组织者和参与者来说都至关重…

WebService的wsdl详解

webservice服务的wsdl内容详解&#xff0c;以及如何根据其内容编写调用代码 wsdl示例 展示一个webservice的wsdl&#xff0c;及调用这个接口的Axis客户端 wsdl This XML file does not appear to have any style information associated with it. The document tree is shown…

编译aosp刷入pixel 真机得问题记录

编译aosp要做什么&#xff08;ubuntu下编译问题相对少&#xff09; 需要vmware并且已经安装了ubuntu镜像系统 直接切换到root 避免后期避免麻烦 参考地址 https://mp.weixin.qq.com/s/yJp3ijIxykiMmNVYr2V1nQ apt install git //安装git sudo apt install git//给git设置用户…

mysql事务 事务并发问题 隔离级别 以及原理

mysql事务 简介&#xff1a;事务是一组操作的集合&#xff0c;它是一个不可分割的工作单位&#xff0c;事务会把所有的操作作为一个整体一起向系统提交或撤销操作请求&#xff0c;即这些操作要么同时成功&#xff0c;要么同时失败。 事务四大特性 原子性&#xff08;Atomici…