- 主题:c++ 定义变量语法,这个很少见
哈哈,我最近用过。
序列化的代码,定义成员变量的类模板<UrclassT, memberT>,声明指针,UrClassT::memberT* p,指向某个成员变量,可以get/get。
客户代码提前注册每个成员变量。
【 在 ilovecpp 的大作中提到: 】
: 我从来没见人用过。类里面要真有那么多同类型成员变量,需要选择的话,为什么不扔数组里呢?猜测就是因为有成员函数指针(好歹还 ...
--
FROM 1.80.221.*
没学过C,从cpp开始学编程,学的也不精,面向对象思维根深蒂固。
大概知道你说的是什么,根据类内存布局,sizeof(T)偏移,
还考虑8字节对齐、先bool再double,末尾放个char[0]?
一直没掌握。老派程序员的世界。
【 在 ilovecpp 的大作中提到: 】
: 用offsetof宏是不是也可以?继承场景下会有区别吗,好像也没有。
: offsetof结果就是个整数,不像成员指针带着对象类型,前者代码膨胀可能都小很多。
--
FROM 1.86.56.*
https://eliasdaler.github.io/meta-stuff/照着这个写的,精简后就200行。看他github上的源码更直接。
我模仿了他的思路,tuple + index_sequence,前面的函数指针
只是个细节。
我的主要工作是特化类型,对接我用的平台数据类型和序列化接口。
你发个offset的链接。
【 在 ilovecpp 的大作中提到: 】
: 不我觉得你不知道。不如把你说的序列化代码写一段例子出来看看。
--
FROM 1.86.56.*
但它完全没必要地带了T和Class类型,导致你每个Class都对应一套Member,
每个class都对应一套Member,——这点有道理。我看到这种方案时,第一反应也是这。我主要是担心编译慢。在另一处看了类似方案,目前主流都是每个类背后一个tuple。于是就随流了。
Class类型和void*对比,不能完全说多余。类型安全,不会传错obj。这是除了面向对象,我学cpp排第二的根深蒂固的思想。
offsetof哈,我以为得自己手写,原来编译器支持的啊。我确实不知。刚查了下,搞不懂standard layout的requirement。 不如T Class::* 这种语法,虽然佶屈聱牙,但是浅,心智负担不大。
【 在 ilovecpp 的大作中提到: 】
:
: 很简单,它这个Member类完全可以与对象类型无关:
: template <typename T>
: ...................
--
FROM 1.80.241.*
*(int*)buf是不可避免的。我从reinterpret_cast这种就可以反证,虽然我从没用过。
我说的是把ClassB* obj 传给 ClassA 的Member.FromJson。类的类型错误和属性的属性的类型错误,我认为是两个问题,起码是有距离的两个问题。
这种错误多大概率、预防这种错误有多大价值、下多大力气,或者说程序员应该多大程度自律,见仁见智了。老派C程序员可能是古典自由主义,我这种半吊子cpp程序员,可能是新保守主义。:-)
【 在 ilovecpp 的大作中提到: 】
: 你只要保证自己的实现正确,MetaHolder<Class>里没有错放别的类的Member,类型安全就没有问题。用户接触不到你内部的void*。
: 序列化里用void*那可太多了。难道我从二进制反序列化int时候就不能*(int*)buf,非得读四个字节出来用位操作拼么?序列化本来就是一个不讲究类型安全的场合。
--
FROM 1.80.241.*
我的初衷是用户用的不对,编译时能提示。这种不叫类型错误吗?我是不是用错术语了……你说只有后者,我没跟上。
接下来就都是请教的时间了。我还是懂得太少了~
std::map的树节点擦掉了类型吗,愿闻其详哈。
往map<k, v1> 里插入 {k, v2}?
【 在 ilovecpp 的大作中提到: 】
: 这种错误的概率嘛,我们先问一下,是用户用得不对可以引发类型错误,还是只有你这两百行代码里面的bug可以引发类型错误?应该是只有后者。
: 我觉得那就无所谓了。这两百行代码里的bug可以引发的错误那可多了去了,不差这个。
: 你看std::map里面的树节点为什么要擦除掉元素类型,它不怕树里面混进别的类型的元素?不怕的嘛。
--
FROM 1.80.241.*
跟上了一些,我们继续。
面向用户的接口,一是member函数,用于注册,生成一个“属性”,不绑定某个类。
另一个,发起序列化本身,是怎样的? 我想的是链接里,
loopClassAndDoSth(obj*,json)
所以担心传错obj。
【 在 ilovecpp 的大作中提到: 】
: 你面向用户的接口,比如member函数/宏,可以带Class类型。但你内部实现,比如Member,并不一定要带类型。接口已经保证了类型正确。
: std::map同理。接口当然不允许你插入类型不对的元素。但内部比如维护红黑树的代码,并不需要知道元素类型,是实现成非模板普通函数的。
--
FROM 124.114.151.*
哦,是啦。是ClassA::ToJson,ClassB::ToJson这样的。
我需要一点时间,看下为什么我没设计成这样子。而是从了链接的方案,
设计成了一个 free function。而不是类的method。
【 在 ilovecpp 的大作中提到: 】
: 你面向用户的接口,比如member函数/宏,可以带Class类型。但你内部实现,比如Member,并不一定要带类型。接口已经保证了类型正确。
: std::map同理。接口当然不允许你插入类型不对的元素。但内部比如维护红黑树的代码,并不需要知道元素类型,是实现成非模板普通函数的。
--
FROM 124.114.151.*
free function,是为了解耦Class和Json,因为以后可能变格式,存xml,存其它格式。
【 在 ilovecpp 的大作中提到: 】
: 你面向用户的接口,比如member函数/宏,可以带Class类型。但你内部实现,比如Member,并不一定要带类型。接口已经保证了类型正确。
: std::map同理。接口当然不允许你插入类型不对的元素。但内部比如维护红黑树的代码,并不需要知道元素类型,是实现成非模板普通函数的。
--
FROM 1.80.241.*