将POD结构体强制转换为派生类型

Casting a POD struct into a derived type

本文关键字:派生 类型 转换 POD 结构体      更新时间:2023-10-16

在处理遗留项目时,我遇到了以下模式:POD结构用于在网络上传输数据。

struct PODType {
    // some data
    int data;
};

在接收端,数据被接收为POD类型的对象。随后,从PODType派生出一个类,并将接收到的对象用c风格强制转换为派生类,以使用一些方法访问数据。

class DerivedFromPOD: public PODType {
public:
    // some methods
    int f(int x) {return data+x;}
protected:
    // some methods
};
PODType pod;
receive(&pod);
DerivedFromPOD* d = (DerivedFromPOD*)&pod;
int i = d->f(10);

派生类具有公共和受保护的方法,因此它不再是POD。我知道这是对继承的滥用,但它在代码库中已经存在很长时间了。

我想知道这是否保证从标准的角度(c++ 03或c++ 98)工作。派生类没有任何自己的数据成员或虚拟函数,但我不确定它是否保证内存布局是相同的,因为一个是POD,另一个不是。编译器是否强制安排DerivedFromPOD,使d.data的地址与DerivedFromPOD类型的对象d的地址相同,因为它是POD基类?

这当然不能保证在一般情况下工作(尝试向派生类添加虚函数),并且是正式未定义的行为。(我也不明白如何使用struct来帮助在网络上传输数据。

DerivedFromPOD*指针可以安全地转换为PODType*指针。因此,我们可以确信继承的PODType在内存中的布局是相同的。

然而,当反向强制转换时,DerivedFromPOD可以在内存中由一些编译器数据组成,然后是PODType数据,然后是一些额外的编译器数据。

如果你使用c风格的强制转换,或者使用static_cast<>强制转换,编译器会假设你知道你在做什么,并调整指针地址,以便DerivedFromPODPODType部分将正确指向正确的区域。

但是,不要尝试使用从DerivedFromPOD访问其他数据的方法,因为它们在内存中是不正确的。

特别是,不要使用任何虚方法,因为VMT (virtual Method Table)不存在。