Tom*_*Tom 8 c++ static-cast reinterpret-cast
我正在努力学习static_cast和reinterpret_cast.
如果我是正确的,标准(9.2.18)说reinterpret_castpod数据是安全的:
指向POD结构对象的指针(适当地使用a转换)
reinterpret_cast指向其初始成员(或者如果该成员是位字段,则指向它所驻留的单元),反之亦然.[注意:因此,在POD-struct对象中可能存在未命名的填充,但不是在其开头,以实现适当的对齐. - 结束说明]
我的问题是如何严格解释这一点.例如,布局兼容性足够吗?如果没有,为什么不呢?
对我来说,以下示例显示了严格的"仅POD有效"解释似乎是错误的示例.
class complex_base // a POD-class (I believe)
{
public:
double m_data[2];
};
class complex : public complex_base
{ //Not a POD-class (due to constructor and inheritance)
public:
complex(const double real, const double imag);
}
double* d = new double[4];
//I believe the following are valid because complex_base is POD
complex_base& cb1 = reinterpret_cast<complex_base&>(d[0]);
complex_base& cb2 = reinterpret_cast<complex_base&>(d[2]);
//Does the following complete a valid cast to complex even though complex is NOT POD?
complex& c1 = static_cast<complex&>(cb1);
complex& c2 = static_cast<complex&>(cb2);
Run Code Online (Sandbox Code Playgroud)
此外,如果complex_base::m_data受到保护可能会破坏(意味着complex_base不是吊舱)?[编辑:我如何保护自己/检测此类破损]
在我看来,布局兼容性应该足够了 - 但这似乎不是标准所说的.
编辑:谢谢你的答案.他们也帮助我找到了这个, http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2342.htm
我相信以下内容是有效的,因为complex_base是POD
你错了.d[0]不引用complex_base对象的第一个成员.因此,它的对齐可能对于一个complex_base对象来说不够好,因此这样的演员表是不安全的(并且你引用的文字不允许).
即使复杂不是POD,以下是否完成了对复杂的有效转换?
cb1并且cb2不指向类型对象的子对象complex,因此static_cast产生未定义的行为.参见C++ 03的5.2.9p5
如果类型"cv1 B"的左值实际上是类型D的对象的子对象,则左值引用类型D的封闭对象.否则,未定义强制转换的结果.
仅仅涉及的类型合在一起是不够的.该文本讨论了指向POD结构对象的指针以及指向某个子对象的左值.复杂和complex_base是标准布局对象.C++ 0x规范说,而不是你引用的文字:
这是一个不同的问题,不是关于您的示例代码.是的,要求POD-ness太严格了.在C++ 0x中,这被认可,并且给出了一个更宽松的新要求"标准布局".我认为,这两个complex 和 complex_base是标准的布局类,由C++ 0x中定义.C++ 0x规范说,而不是你引用的文字:
指向标准布局结构对象的指针,使用reinterpret_cast进行适当转换,指向其初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然.
我将其解释为允许将指针转换为a double,实际指向complex成员(通过继承成员),将其转换为a complex*.标准布局类是没有包含非静态数据的基类,或者只有一个包含非静态数据的基类的类.因此,有一个独特的"初始成员".