C++中类型转化

2023-10-27

       对象类型向上向下转化(对象转化是对象间的按成员赋值,有新的存储被分配(有新对象产生)

       类型指针向上向下转化(转化后没有得到引得对象,也可以说没有新的存储分配,我们只是通过一个小的(转化后的对象的大小)视角去看待这个对象。因此在诸如对象的释   放 等方面会牵扯一些问题,语言单独支持的虚析构就是为了解决这种转化后对象释放不对称的问题。类层次结构中类型之间的转化不同于普通或内置类型之间的转化,最明显得区别是转化前后两个对象的指针指向的不是相同的的地址。其实可以说:派生类指针向基类指针转化实际上市派生类中基类子对象的地址赋给目标对象指针(图示)

 

 

 

类对象的静态类型(声明时的类型)和动态类型(指向的实际类型,被赋值的类型)

考虑下列初始化 它用一个派生类 NameQuery 对象的地址初始化一个 Query 基类指针
Query *pb = new NameQuery( "sprite" );

如果我们调用在 Query 基类中定义的虚拟函数 如
pb->eval(); // 调用 NameQuery::eval()
则调用派生的 NameQuery 类实例 除了 在 Query 基类中被声明 并且在 NameQuery派类中被改写 的虚拟函数之外, 我们没有办法通过 pb 直接访问 NameQuery 的成员
1 如果 Query 和 NameQuery 都声明了一个同名的非虚拟成员函数, 则通过 pq 调用的总是Query 的实例

2 类似地 如果 Query 和 NameQuery 都声明了一个同名的数据成员 ,则通过 pq 总是访问 Query 的实例
3.如果 NameQuery 引入了一个在 Query 中不存在的虚拟函数 比如 suffix() 那么试图通过 pq 调用它就会导致一个编译时刻错误:
  // 错误: suffix() 不是 Query 的成员
  pb->suffix();

4 类似地 如果我们试图通过 pq 访问 NameQuery 的数据成员或非虚拟成员函数 也会产生一个编译时刻错误:
// 错误: _name 不是 Query 的成员
pb->_name;

在 C++中 基类指针只能访问在该类中被声明或继承的数据成员和成员函数包括虚拟成员函数 ,而与它可能指向的实际对象无关 ,把一个成员函数声明为虚拟的,只推延了
在程序执行期间根据pq 指向的实际类类型, 对于要调用的实例的解析过程


(自己再vc的环境中写代码验证了一番(不知道对不对,自己先记着)派生类从基类那里继承了数据成员,在派生类对象中基类子对象(如果存在虚拟函数的话)的的虚函数表指针与派生类对象的虚函数表指针是一个变量,都存在对象存储空间的最前方。如果派生类对象存在虚拟函数(则有虚函数表指针)而基类没有虚拟函数(没有虚函数表指针),则打印出来的派生类中的基类子对象时是没有此指针的。

如:

class A{
public:
 int a;
 virtual void parent(){}
 virtual void func(){}
 A(int x){a=x;}
};

class B :public A{
public :
 int b;
 virtual void func(){}
 virtual void parent(){}
 virtual void child(){}
 B(int y):A(2){b=y;}
};
 void main()
 {
  B b(1);
  char * pb=(char *)&b;
  A *pa=&b;
  char *pc=(char *)pa;
  for (int i=0;i<sizeof B;i++)
   cout<<(int)pb[i]<<" ";
  cout<<endl;
  for(i=0;i<sizeof A;i++)
   cout<<(int)pc[i]<<" ";
  cout<<endl;
  cout<<"pa="<<pa<<"  "<<"&b="<<&b<<endl;    //比较两个对象(派生类对象和其中的基类子对象的开始地址是否相同)
  //   cout<<sizeof A <<"  "<<sizeof B<<endl;
  
 }

结果为:44  -16  70 0 2 0 0 0 1 0 0 0

                44  -16  70 0 2 0 0 0

                pa=0012ff74  &b=0012ff74

    //44 -16 70 0化成十六进制是0x0046f02c(是虚函数表的地址)

 

 

class A{
public:
 int a;
 A(int x){a=x;}
};

class B :public A{
public :
 int b;
 virtual void func(){}
 virtual void parent(){}
 virtual void child(){}
 B(int y):A(2){b=y;}
};
 void main()
 {
  B b(1);
  char * pb=(char *)&b;
  A *pa=&b;
  char *pc=(char *)pa;
  for (int i=0;i<sizeof B;i++)
   cout<<(int)pb[i]<<" ";
  cout<<endl;
  for(i=0;i<sizeof A;i++)
   cout<<(int)pc[i]<<" ";
  cout<<endl;
  cout<<"pa="<<pa<<"  "<<"&b="<<&b<<endl;    //比较两个对象(派生类对象和其中的基类子对象的开始地址是否相同)
  //   cout<<sizeof A <<"  "<<sizeof B<<endl;
  
 }

结果为:44  -16  70 0 2 0 0 0 1 0 0 0

                2    0   0  0

                pa=0012ff78  &b=0012ff74

    //44 -16 70 0化成十六进制是0x0046f02c(是虚函数表的地址),此时派生类对象有此指针,而基类子对象没有。

 

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

C++中类型转化 的相关文章

  • SL4 AutoCompleteBox 重复筛选结果问题

    我在 AutoCompleteBox 过滤方面遇到问题 它似乎记住了之前的过滤器 例如 我输入 A 它会返回 1 项 我删除 A 并输入 Z 这应该返回 1 项 问题是它返回 A 过滤器加上 Z 的结果 我删除 Z 并输入 S 这会带回 2
  • 为什么opencv videowriter这么慢?

    你好 stackoverflow 社区 我有一个棘手的问题 我需要你的帮助来了解这里发生了什么 我的程序从视频采集卡 Blackmagic 捕获帧 到目前为止 它工作得很好 同时我用 opencv cv imshow 显示捕获的图像 它也工
  • C# 中的协变和逆变

    首先我要说的是 我是一名正在学习 C 编程的 Java 开发人员 因此 我会将我所知道的与我正在学习的进行比较 我已经使用 C 泛型几个小时了 我已经能够在 C 中重现我在 Java 中知道的相同内容 除了几个使用协变和逆变的示例 我正在读
  • 关闭 XDOCUMENT 的实例

    我收到这个错误 该进程无法访问文件 C test Person xml 因为它是 被另一个进程使用 IOException 未处理 保存文件内容后如何关闭 xml 文件的实例 using System using System Collec
  • 通过引用传递时取消引用指针

    当通过引用传递给函数时取消引用指针时会发生什么 这是一个简单的例子 int returnSame int example return example int main int inum 3 int pinum inum std cout
  • 使用反射获取基类的受保护属性值

    I would like to know if it is possible to access the value of the ConfigurationId property which is located in the base
  • 用 C# 制作 Vista 风格的应用程序

    我正在运行 Windows Vista 并且希望外观看起来像常规 Vista 程序 有没有关于如何构建 Vista 风格应用程序的真正好的教程 文章 我还想学习如何使用本机代码并将其转换为 C 如this http bartdesmet n
  • 使用 openssl 检查服务器安全协议

    我有一个框架应用程序 它根据使用方式连接到不同的服务器 对于 https 连接 使用 openssl 我的问题是 我需要知道我连接的服务器是否使用 SSL 还是 TLS 以便我可以创建正确的 SSL 上下文 目前 如果我使用错误的上下文尝试
  • 抽象类或接口。哪种方式是正确的?

    有两种方法可以选择抽象类或接口 微软解决方案和Oracle解决方案 微软 设计指南 请使用抽象 在 Visual Basic 中为 MustInherit 类而不是接口来将协定与实现分离 http msdn microsoft com en
  • QThread - 使用槽 quit() 退出线程

    我想在线程完成运行时通知对象 但是 我无法让线程正确退出 我有以下代码 处理器 cpp thread new QThread tw new ThreadWorker connect tw SIGNAL updateStatus QStrin
  • c# 如何生成锦标赛括号 HTML 表

    所以我已经被这个问题困扰了三个星期 但我一生都无法弄清楚 我想做的是使用表格获得这种输出 演示 http www esl world net masters season6 hanover sc2 playoffs rankings htt
  • 更改其他页面的主窗口内容

    在 WPF 应用程序的主窗口中 我有一个 Badged 元素 来自材料设计 这是我的代码
  • C# 中处理 SQL 死锁的模式?

    我正在用 C 编写一个访问 SQL Server 2005 数据库的应用程序 该应用程序是数据库密集型的 即使我尝试优化所有访问 设置适当的索引等 我预计迟早会遇到死锁 我知道为什么会发生数据库死锁 但我怀疑我能否在某个时候发布不发生死锁的
  • 从包含大量文件的目录中检索文件

    我的目录包含近 14 000 000 个 wav 格式的音频样本 所有普通存储 没有子目录 我想循环浏览文件 但是当我使用DirectoryInfo GetFiles 在该文件夹上 整个应用程序冻结了几分钟 可以用另一种方式完成吗 也许读取
  • 为什么WCF中不允许方法重载?

    假设这是一个ServiceContract ServiceContract public interface MyService OperationContract int Sum int x int y OperationContract
  • 如何不在类中实现接口的功能?

    面试时面试官问了我以下问题 但我不知道这个问题的答案是什么 请帮忙 如果我不想 我必须做什么 在我的类中实现一个函数 在接口中声明为 由我班实施 Edited 我正在使用 NET 和 C 如果有人可以提供 C 示例代码示例 那就太好了 Th
  • 在 .NET 中记录 StackOverflowException

    最近 我的 NET 应用程序 asp net 网站 中出现了堆栈溢出异常 我之所以知道该异常是因为它出现在我的 EventLog 中 我知道 StackOverflow 异常无法被捕获或处理 但是有没有办法在它杀死您的应用程序之前记录它 我
  • 理解 C++11 中的 std::atomic::compare_exchange_weak()

    bool compare exchange weak T expected T val compare exchange weak 是 C 11 中提供的比较交换原语之一 它是weak即使对象的值等于 它也会返回 falseexpected
  • 是否有任何不使用公共虚拟方法的正当理由? [关闭]

    Closed 这个问题是基于意见的 help closed questions 目前不接受答案 是否有任何不使用公共虚拟方法的正当理由 我在某处读到我们应该避免使用公共虚拟方法 但我想向专家确认这是否是有效的声明 对于良好且稳定的 API
  • 如何确定给定方法可以抛出哪些异常?

    我的问题和这个真的一样 找出 C 中方法可能抛出的异常 https stackoverflow com questions 264747 finding out what exceptions a method might throw in

随机推荐

  • WSL2默认DNS配置导致无法访问网络

    问题分析 1 进入wsl ping www baidu com 不通 2 本机cmd ping www baidu com 正常 3 把本机ping 百度的ip拿出来 用wsl直接ping 百度的ip正常 通过此步骤基本可以判断是WSL2默
  • 【GitHub.io/Github Pages使用教程】从头开始搭建自己的Github Pages,打造个人博客网站,展示个人简历、项目、文档或想要与世界共享的任何其他内容

    巨人半边莲 如果你曾征服乞力马扎罗山 留意过海拔 3 657 4 267 米处的尖顶植物 这种植物有时形似绿色大柱子 或 花序 从中间长出花序 那么你就可能看到许多巨人半边莲 这些植物生长在非洲最高山上 事实上 巨人半边莲是乞力马扎罗山上发
  • 基于Matlab的2ASK、2PSK性能仿真

    这里我们将简单的在Matlab中进行2ASK与2PSK的仿真 比较实际误码率与理论误码率 最终做出相应的曲线 2ASK的仿真 我们首先来2ASK的看一下程序框图 产生 0 1 随机数序列这里我们使用的是Matlab中randi imin i
  • Thinkphp5 联表(联合、关联、join)查询

    Db table think artist gt alias a gt join think work w a id w artist id gt join think card c a card id c id gt select joi
  • ps2020闪退_Adobe Photoshop 2020总是打不开,闪退,怎么回事,解决方法

    尽管还没有到2020年 但adobe公司更新软件的步伐没有停止 adobe 2020全家桶系列软件已经发布 其中就包括大家最喜欢的图像设计大师Photoshop 2020 我在第一时间也给大家分享了Photoshop2020简体中文版 许多
  • 微分动态规划的基本思想

    吴恩达cs229第19课 微分动态规划这一部分 看了两遍才看明白 赶紧记下来 微分动态规划是基于LQR 线性二次型 的 后者能够比较简洁地计算最优策略 但要基于一个前提 就是 t 1 时刻的状态 是 t 时刻的状态和 t 时刻采取行为的线性
  • LaTeX常用语法查询(自用)

    文章目录 LaTex文档结构 添加作者 标题 日期 章节和段落 插入目录 插入数学公式 两种插入模式 上下标和空格 根式与分式 符号 括号 省略号 矩阵 插入图片 插入表格 编辑器 离线编辑 在线编辑 分点 itemize 参考文献插入链接
  • 使用golang的pprof包对程序进行性能分析

    golang提供pprof包 可以监控golang程序的堆栈 cpu的耗时等性能信息 下边就说一下这个pprof包的使用 1 首先是引入 在两个地方可以引入 net http pprof runtime prof 其中 net http p
  • 尺寸汇总

    尺寸汇总 获取视口的宽高 含滚动条 window innerWidth window innerHeight 不含滚动条 document documentElement clientWidth document documentEleme
  • python使用matplotlib实现折线图的绘制

    一 意义 数据可视化可以以简洁的方式呈现出数据 发现众多数据中隐藏的规律和意义 Matplotlib是一个数学绘图库 利用它可以制作简单的图表 散点图 折线图 然后 将基于漫步概念生成一个更有趣的数据集 根据一系列随机决策生成的图表 本文我
  • 数据结构(9)之带权图

    1 带权图中 边带有一个数字 叫做权 它可能代表距离 耗费 时间或其他意义 2 带权图用来最常解决的问题是最短路径问题 pps 3 带权图的最小生成树中有所有的顶点和连接它们的必要的边 且这些边的权值最小 4 优先级队列的算法可用于寻找带权
  • Andriod中如何新建lunch项

    Andriod编译过程一般为 1 source build envsetup sh 加载命令 在项目根目录下 purple code a A code20211126 sdm660 目录 备注 在envsetup sh里将执行vendor和
  • 微服务 - 搭建Consul集群服务,Consul配置中心

    传统配置文件的弊端 静态化配置 例如env文件 配置文件无法区分环境 配置文件过于分散 历史版本无法查看 配置中心如何解决的呢 配置中心的思路是把项目中的配置参数全部放在一个集中的地方来管理 并提供一套标准的接口 当各个服务需要获取配置的时
  • [报名中] 腾讯技术专家为你揭秘"音视频及融合通信技术"

    导语 6月29日 北京东直门亚朵S酒店 云 社区邀您参加 音视频及融合通信技术 沙龙活动 深度探讨音视频及融合通信技术的发展及实践 领略前沿 共创价值 数字多媒体技术的不断发展对音视频及融合通信技术提出了怎样的要求呢 本期沙龙将邀请腾讯技术
  • qt中使用QStringLiteral宏来实现带参数的输出

    叙述 在QStringLiteral宏中输入字符串 但是字符串中有些值想用变量来输出 直接上代码 qDebug lt
  • futter开发错误积累

    注 后面添加以倒序方式添加 26 错误 RangeError index Invalid value Not in inclusive range 0 7 8 指示您的数组索引是从即0到7 但您正在尝试访问不存在的第8个索引的值 25 错误
  • 2021全国职业技能大赛安徽省合肥市“网络空间安全赛项”赛题及赛题解析(超详细)

    2021年中职组 网络空间安全 赛项 一 合肥市竞赛任务书 二 任务书解析 三 不懂的可以私信博主 一 合肥市竞赛任务书 一 竞赛时间 8 00 11 00 共计3小时 二 竞赛阶段 竞赛阶段 任务阶段 竞赛任务 竞赛时间 分值 第 阶段
  • SG90舵机的使用

    1 SG90舵机官方数据 尺寸 21 5mmX11 8mmX22 7mm 重量 9克 1kg 1公斤 2斤 无负载速度 0 12秒 60度 4 8V 0 002s 度 堵转扭矩 1 2 1 4公斤 厘米 4 8V 使用温度 30 60摄氏度
  • dubbo消费者源码解析

    一 服务消费者核心类ReferenceBean public void afterPropertiesSet throws Exception if applicationContext null BeanFactoryUtils bean
  • C++中类型转化

    对象类型向上向下转化 对象转化是对象间的按成员赋值 有新的存储被分配 有新对象产生 类型指针向上向下转化 转化后没有得到引得对象 也可以说没有新的存储分配 我们只是通过一个小的 转化后的对象的大小 视角去看待这个对象 因此在诸如对象的释 放