我想使用fwrite将对象写入顺序文件.班级就像
class A{
int a;
int b;
public:
//interface
}
Run Code Online (Sandbox Code Playgroud)
当我将一个对象写入文件时 我在游荡,我可以fwrite( this, sizeof(int), 2, fo)
用来编写前两个整数.
问题是:即使this
在对象的最开头存在虚拟表,也保证指向对象数据的开始.所以上面的操作是安全的.
不,这不对.你可以使用fwrite(&a, sizeof(int), 2, fo)
,但你也不应该.在安全方面,漫步原始内存很少是一个好主意,因为你不应该依赖特定的内存布局.有人可以c
在a
和之间引入另一个变量b
,而不会注意到他正在破坏你的代码.如果要访问变量,请明确执行此操作.不要只访问您认为变量的内存或上次检查时的内存.
this
提供对象的地址,它不一定是第一个成员的地址。唯一的例外是所谓的标准布局类型。来自 C++11 标准:
\n\n\n(9.2/20) 指向标准布局结构对象的指针,使用适当转换
\nreinterpret_cast
指向其初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然。[ 注意:因此,标准布局结构对象内可能存在未命名的填充,但在其开头则不然,这是实现适当对齐所必需的。\xe2\x80\x94 尾注]
这是标准布局类型的定义:
\n\n\n\n\n(9/7) 标准布局类是这样的类:
\n\n
\n \xe2\x80\x94 没有非标准布局类类型(或此类类型的数组)或引用的非静态数据成员,
\n \xe2\x80\x94 没有虚函数 (10.3) 和虚基类 (10.1),
\n \xe2\x80\x94 对所有非静态数据成员具有相同的访问控制(第 11 条),
\n \ xe2\x80\x94 没有非标准布局基类,
\n \xe2\x80\x94 要么在最远的派生类中没有非静态数据成员,并且最多有一个具有非静态数据成员的基类,或者没有带有非静态数据成员的基类,并且
\n \xe2\x80\x94 没有与第一个非静态数据成员类型相同的基类。[108][108]这确保了具有相同类类型且属于同一最派生对象的两个子对象不会分配在同一地址 (5.10)。
\n
请注意,对象类型不必是 POD——具有上面定义的标准布局就足够了。(POD 都具有标准布局,但除此之外,它们还可以轻松构建、轻松移动和轻松复制。)
\n\n据我从您的代码中可以看出,您的类型似乎是标准布局(确保所有非静态数据成员的访问控制相同)。在这种情况下,this
确实会指向初始成员。关于将其用于序列化目的,标准实际上明确指出:
\n\n\n(9/9) [ 注意:标准布局类对于与用其他编程语言编写的代码进行通信非常有用。它们的布局在 9.2 中指定。\xe2\x80\x94 尾注]
\n
当然这并不能解决所有问题问题。特别是,您将无法获得序列化数据的可移植性(例如,由于字节序不兼容)。
\n 归档时间: |
|
查看次数: |
240 次 |
最近记录: |