首页 文章

将POD结构转换为派生类型

提问于
浏览
1

在处理遗留项目时,我遇到了以下模式: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基类一样?

2 回答

  • 1

    它's certainly not guaranteed to work in general (try adding a virtual function to the derived class), and is formally undefined behavior. (I also don't看看 struct 如何用于帮助通过网络传输数据 . 不同的机器将以不同的方式表示 . )

  • 2

    DerivedFromPOD* 指针可以安全地转换为 PODType* 指针 . 所以我们确信内存中继承的 PODType 的布局是一样的 .

    但是,当在相反的方向上进行转换时, DerivedFromPOD 可以在内存中用一些编译器数据组成,然后是 PODType 数据,然后是一些额外的编译器数据 .

    如果您正在使用C样式转换或 static_cast<> 进行此转换,编译器将假设您知道您正在做什么并调整指针地址,以便 DerivedFromPODPODType 部分将正确指向好区域 .

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

    特别是,不要使用任何虚拟方法,因为VMT(虚拟方法表)不存在 .

相关问题