将POD结构体强制转换为派生类型
Casting a POD struct into a derived type
在处理遗留项目时,我遇到了以下模式: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<>
强制转换,编译器会假设你知道你在做什么,并调整指针地址,以便DerivedFromPOD
的PODType
部分将正确指向正确的区域。
但是,不要尝试使用从DerivedFromPOD
访问其他数据的方法,因为它们在内存中是不正确的。
特别是,不要使用任何虚方法,因为VMT (virtual Method Table)不存在。
- 在 C++ 中用派生类型重写成员函数
- 在 C++ 中将对象转换为派生类型
- C++如果采用类类型的函数被传递派生类型,有没有办法给出错误?
- 返回派生类型时出现协变类型错误
- 如何模板化堆栈分配的多态指针数组到接口,包括派生类型的相应点?
- 基于派生类型的编译时行为分支
- 按类型排序向量并按类型或派生类型搜索
- 为什么"运算符<<"不适用于指向派生类型的成员?
- 无法返回派生类型的标准::unique_ptr<>
- 无法从派生类型的作用域访问另一个实例的受保护成员
- dynamic_cast到具有未知模板参数的派生类型
- 派生类型的成员
- 视觉C++ dynamic_cast返回 NULL,尽管对象是派生类型
- 在运算符中动态强制转换为派生类型<<
- 如何在不转换回基类类型的情况下返回派生类型的对象?
- 将派生指针分配给C 中的其他派生类型
- 如何将派生类型的对象放在用于基本类型的向量中
- C++ - 无法将派生类型作为基类型列表传递给构造函数
- 如何在基本类型参考中存储对派生类型的参考
- 统一处理具有协变类型的函数指针(如何使用派生类型调用回调?