C++的反射和序列化

Gamasutra上有篇文章讲得挺细的: Sponsored Feature: Behind the Mirror - Adding Reflection to C++

  • RTTI
    • 在Class声明后加入RTTI宏的做法几乎快成各种引擎的标配了, 谁叫C++的rtti太弱来着.
    • 之前只是认为自己实现RTTI的原因是dynamic_cast的效率不高和对象工厂的需要, 原来关掉这个编译选项还可以减少占用的内存
  • Field(Property)
    • 实现反射必须有一些属性成员的描述类, 这些信息目前看到三种实现方法
      • 使用工具/编译器中间信息等根据C++代码解析生成(Havok冒似是这种实现). 不推荐, 见原文
      • 使用各种模板+宏像RTTI那样进行注册, 查询方便, 缺点是会增加启动时间和内存占用, 难于单步调试
      • 使用访问者模式, 在需要查询信息时才创建, 编码比较灵活, 但是访问起来比较慢
      • 一般都是记录成员变量相对于class/struct的offset和size, 再根据实例指针计算出内存地址
  • Method
    • 目前还没有看到把方法也做了反射的引擎, 到是cppreflect里有实现. 编码上越简洁越好, 复杂的可以使用脚本代替
  • Clone
    • 做了反射的另一个好处就是对象可以深度拷贝, 这也是Prefab/Template的基础要求
  • Serialization
    • 有了反射做序列化相当的方便, 如果没有的话就像GameBryo那样做也凑合
    • 把Name(或CRC)与Value一起序列化后就可以做到版本的兼容, 对于成员属性改动频繁的情况很实用
    • 对于重复性的数据的二进制序列化可以进行压缩, 如数组
    • 对于内存Buffer的XML序列化, 可以使用base64编码成字符串
  • Inheritance
    • 数据继承, 或者要数据拷贝, 就是对象实例之间的数据有继承关系, 只保存相对于父实例(Template)不同的数据
  • Others
    • 以前做Delegate实现的时候只接触过成员函数指针, 没想到还有个成员变量指针, C++真是博大精深
    • Enum和Container需要特殊对待
    • 如果要反射到.net的PropertyGrid, 可以使用ICustomTypeDescriptor构造动态属性对象, 或者使用Reflection.Emit动态编译生成类型

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏進无尽的文章

编码篇-低耦合代码注入

我下面要将的内容也许网上已经有很多相关的介绍了,但是我还是会写出这篇文章,一来是对自己学习的总结,虽然总结的有些晚,如果你仔细看,会发现我的文章有别处没有的内容...

1022
来自专栏Spark学习技巧

Flink DataSet编程指南-demo演示及注意事项

Flink中的DataStream程序是对数据流进行转换的常规程序(例如,过滤,更新状态,定义窗口,聚合)。数据流的最初的源可以从各种来源(例如,消息队列,套接...

3.4K12
来自专栏大史住在大前端

野生前端的数据结构基础练习(2)——队列

循环队列书中并没有提及,它是一种特殊的队列。简单理解就是将基本队列只当做存储结构,而使用front和rear两个指针分别代表队列的头和尾,实际对外表现的队列是f...

2043
来自专栏醒者呆

掌握一门语言Go

摘要:Go语言的优势不必多说,通过本篇文章,让我们花时间来掌握一门外语,Let's Go! 关键字:Go语言,闭包,基本语法,函数与方法,指针,slic...

4139
来自专栏北京马哥教育

十分钟完成Bash 脚本进阶!列举Bash经典用法及其案例

前言:在linux中,Bash脚本是很基础的知识,大家可能一听脚本感觉很高大上,像小编当初刚开始学一样,感觉会写脚本的都是大神。虽然复杂的脚本是很烧脑,但是,当...

1373
来自专栏北京马哥教育

十分钟完成Bash 脚本进阶!列举Bash经典用法及其案例

? 前言:在linux中,Bash脚本是很基础的知识,大家可能一听脚本感觉很高大上,像小编当初刚开始学一样,感觉会写脚本的都是大神。虽然复杂的脚本是很烧脑,但...

3688
来自专栏iOS技术杂谈

iOS runtime探究(五): 从runtime开始深入weak实现机理你要知道的runtime都在这里

你要知道的runtime都在这里 转载请注明出处 https://cloud.tencent.com/developer/user/1605429 本文主要讲解...

3266
来自专栏difcareer的技术笔记

JNI实现源码分析【四 函数调用】正文0x01:dvmCallMethodV0x02:nativeFunc0x03: 何时赋值

有了前面的铺垫,终于可以说说虚拟机是如何调用JNI方法的了。JNI方法,对应Java中的native方法,所以我们跟踪对Native方法的处理即可。

934
来自专栏静晴轩

lua表排序

Lua作为一种很强大且轻量级脚本语言的存在,对于掌握其几乎无所不能的Table(其实就是一个Key Value的数据结构,它很像Javascript中的Obje...

42411
来自专栏JavaEdge

Netty 源码深度解析(八) - 解码

就像很多标准的架构模式都被各种专用框架所支持一样,常见的数据处理模式往往也是目标实现的很好的候选对象,它可以节省开发人员大量的时间和精力。

1151

扫码关注云+社区