我正在尝试了解static_cast
and reinterpret_cast
.
如果我是正确的,标准(9.2.18)说的是reinterpret_cast
pod 数据是安全的:
指向 POD 结构对象的指针,
使用适当转换reinterpret_cast
, 指向其
初始成员(或者如果该成员是
位域,然后到其中的单位
它驻留),反之亦然。 [注:因此可能有未命名的
在 POD 结构对象内填充,但不在其开头,这是实现所需的
适当的对齐。 - 结尾
笔记 ]
我的问题是如何严格地解释这一点。例如,布局兼容性是否足够?如果没有,为什么不呢?
对我来说,以下示例显示了严格的“仅 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);
另外,如果complex_base::m_data
受到保护(意味着complex_base
不是 pod)? [编辑:以及我如何保护自己/检测此类破损]
在我看来,布局兼容性应该足够了 - 但这似乎不是标准所说的。
编辑:
感谢您的回答。他们还帮我找到了这个,http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2007/n2342.htm
我相信以下内容是有效的,因为complex_base是POD
您错了。d[0]
不指的是第一个成员complex_base
目的。因此,它的对齐可能不够好complex_base
对象,因此这样的强制转换是不安全的(并且您引用的文本不允许)。
即使complex不是POD,以下内容是否完成了对complex的有效转换?
cb1
and cb2
不指向类型对象的子对象complex
,因此static_cast
产生未定义的行为。参考C++03的5.2.9p5
如果类型“cv1 B”的左值实际上是类型 D 的对象的子对象,则左值引用类型 D 的封闭对象。否则,强制转换的结果是未定义的。
仅将所涉及的类型组合在一起是不够的。文本讨论了指向 POD 结构对象的指针和引用某个子对象的左值。
其余的complex 和complex_base 都是标准布局对象。 C++0x 规范说,而不是您引用的文本:
POD-ness 要求是否太严格?
这是一个不同的问题,与您的示例代码无关。是的,对 POD 性的要求太严格了。在 C++0x 中,这一点得到了认可,并给出了更宽松的新要求,即“标准布局”。我确实认为两者complex
and complex_base
是 C++0x 定义的标准布局类。 C++0x 规范说,而不是您引用的文本:
指向标准布局结构对象的指针(使用reinterpret_cast进行适当转换)指向其初始成员(或者如果该成员是位字段,则指向它所在的单元),反之亦然。
我将其解释为允许将指针强制转换为double
,它实际上指向一个complex
成员(继承成员),被强制转换为complex*
。标准布局类是一种没有包含非静态数据的基类,或者只有一个包含非静态数据的基类的类。这样就有了一个独特的“初始成员”。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)