当前位置: 首页 > news >正文

C++中的对象切割(Object slicing)问题

 在C++中,当我们把派生类对象向上强制转型为基类对象时,会造成对象切割(Object slicing)问题。
 请看下面示例代码:

#include <iostream>
using namespace std;class CBase {
public:virtual ~CBase() = default;virtual void foo() {printf("print in Class CBase,this address:%p\n", this);}
};class CDerive : public CBase {
public:virtual void foo() override {printf("print in Class CDerive,this address:%p\n", this);}
};int main() 
{CBase base;CDerive derive;CBase* pBase = &derive;cout << "\n本次调用的是pBase->CBase::foo()\n\t";pBase->CBase::foo();cout << "\n本次调用的是pBase->foo()\n\t";pBase->foo();cout << "\n本次调用的是 (static_cast<CBase>(derive)).foo() \n\t";(static_cast<CBase>(derive)).foo();
}

 代码运行结果如下:
在这里插入图片描述
 对于前两次调用成员函数foo的结果,大家应该都清楚,pBase是指向派生类对象的基类指针,而foo成员函数是虚函数;因此 pBase->foo() 调用的是派生类方法;pBase->CBase::foo()由于指定了调用CBase的foo函数,因此调用的是基类方法。另外,foo函数打印出来的this指针的地址,显示前两次调用的this指针是同一个,也就是指向子类对象derive。
 关键是最后一次调用的结果,显示调用的是基类方法,并且对象的地址也不是子类对象derive的地址。它的调用语句是:

(static_cast<CBase>(derive)).foo();

 这是为什么呢?这涉及到对象切割(object slicing)。
 在编译时,编译器看到这句是要将派生类对象derive向上强制转为基类对象,因此编译器以所谓的拷贝构造函数把derive中的CBase成分拷贝一份,并把拷贝好的副本作为临时对象放在内存中。在运行期,这个副本(它是CBase对象)调用foo函数时,当然调用的是CBase::foo成员函数了!
 请注意,如果我们把派生类对象的指针向上强制转为基类对象的指针,那么转换后的基类指针仍然指向派生类对象。
 总之,当我们把派生类对象向上强制转型为基类对象时,会经历对象切割(Object slicing),也就是:编译器在内存中创建了一个子类对象的基类成分的副本,这个临时对象与之前的子类对象无关。

http://www.lryc.cn/news/186777.html

相关文章:

  • VxeTable 表格组件推荐
  • 好消息:用 vue3+layui 共同铸造我们新的项目
  • JS中 split(/s+/) 和 split(‘ ‘)的区别以及split()详细解法,字符串分割正则用法
  • MySQL性能调优
  • 如何解决openal32.dll丢失,有什么办法解决
  • Nginx 如何配置http server 、负载均衡(反向代理)
  • windows docker desktop配置加速地址
  • 戏剧影视设计制作虚拟仿真培训课件提升学生的参与感
  • Transformer预测 | Pytorch实现基于Transformer的锂电池寿命预测(NASA数据集)
  • 取出SQLite数据(基本游标)
  • 信息增益,经验熵和经验条件熵——决策树
  • 手摸手系列之批量修改MySQL数据库所有表中某些字段的类型
  • 视频号直播弹幕采集
  • PostgreSQL ash —— pgsentinel插件 学习与踩坑记录
  • HarmonyOS/OpenHarmony原生应用开发-华为Serverless云端服务支持说明(一)
  • 3分钟基于Chat GPT完成工作中的小程序
  • 使用hugo+github搭建免费个人博客
  • 打印字节流和字符流
  • elementplus下载表格为excel格式
  • 聊聊僵尸进程
  • stm32的时钟、中断的配置(针对寄存器),一些基础知识
  • Vue14 监视属性简写
  • 基于docker+Keepalived+Haproxy高可用前后的分离技术
  • 安装配置deep learning开发环境
  • Docker基础(CentOS 7)
  • HTTP的基本格式
  • Qt元对象系统 day5
  • 【audio】alsa pcm音频路径
  • NLP - 数据预处理 - 文本按句子进行切分
  • 【轻松玩转MacOS】常用软件篇