2

在使用旧式投影仪时,我遇到了以下模式: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 基类一样?

4

2 回答 2

2

它当然不能保证一般工作(尝试向派生类添加一个虚函数),并且是形式上未定义的行为。(我也看不出如何struct使用 a 来帮助通过网络传输数据。不同的机器会以不同的方式表示它。)

于 2014-05-13T12:26:55.327 回答
1

指针可以DerivedFromPOD*安全地转换为PODType*指针。所以我们放心,PODType在内存中继承的布局是一样的。

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

如果您使用的是 C 风格的强制转换,或者static_cast<>对于这种强制转换,编译器将假定您知道自己在做什么并调整指针地址,以便正确指向正确区域的PODType部分。DerivedFromPOD

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

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

于 2014-05-13T12:56:42.607 回答