非多态类型的C风格转换

时间:2015-10-14 10:57:22

标签: c++ language-lawyer downcast type-punning

假设我有一个基础struct FOO,基本上是C风格struct

struct FOO
{
    double bar1;
    int bar2;
};

C ++样式struct(具有成员函数,没有成员数据,但没有v-table):

struct bar : public FOO
{
    double getBar1() const;
    int getBar2() const;
};

然后我有一个指针FOO* f实际一个FOO:它是使用FOO* f = new FOO()创建的;是否定义了C风格的演员bar* b = (bar*)(f)

道歉:bar不包含任何数据成员

2 个答案:

答案 0 :(得分:3)

  

是否定义了C风格的转换栏* b =(bar *)(f)?

C-Style演员阵容将永远有效,这就是为什么他们是所有演员阵容中最差的。对于非多态类,您可能希望使用static_cast

但是,在您的情况下,您将走向未定义的行为

bar* b = (bar*)(f);  // = static_cast<bar*>(f)

f的类型为class FOO(即问题FOO* f = new FOO()),而不是class bar。因此,您不应该分配这样的指针。即使您指定,也不得使用它们class bar

P.S. IMO,对最不安全的演员阵容最安全:dynamic_castconst_caststatic_castreinterpret_cast,C式演员。

答案 1 :(得分:1)

我同意iammilind的answer - 您的投射与static_cast相同,并且未定义。

Standard(链接文档实际上是一个草稿,但对于大多数用途并不重要)在第5.2.9节中描述了“未定义强制转换的结果”,其中描述了{{1} }。

但是,由于您的static_cast没有数据成员,因此它是标准布局类,并且与<{1}}的布局兼容。因此,您可以将指针投射到struct bar,然后转到struct FOO

void*

这可以通过foo*更好地用c ++表示:

bar* b = (bar*)(void*)f

这将在5.2.10节中描述:

  

对象指针可以显式转换为不同类型的对象指针...如果T1和T2都是标准布局类型,则结果为reinterpret_cast ...