非多态类型上的 C 风格转换
C-style cast on a non-polymorphic type
假设我有一个基本 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
不包含任何数据成员
Is the C-style cast bar* b = (bar*)(f) defined?
C 风格的转换总是有效的,这就是为什么它们是所有转换中最差的。对于非多态 类,您可能希望使用 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_cast
、const_cast
、static_cast
、reinterpret_cast
、C 风格转换。
我同意 iammilind 的 - 您的转换与 static_cast
相同,但未定义。
Standard(链接文档实际上是草稿,但对大多数用途来说无关紧要)在第 5.2.9 节中说 "the result of the cast is undefined",它描述了 static_cast
。
但是,由于您的 struct bar
没有数据成员,因此它是 标准布局 class,并且 布局兼容 与 struct FOO
。因此,您可以将指针指向 void*
,然后指向 foo*
:
bar* b = (bar*)(void*)f
这在 c++ 中更好地表示为 reinterpret_cast
:
bar* b = reinterpret_cast<bar*>(f)
这在第 5.2.10 节中有描述:
An object pointer can be explicitly converted to an object pointer of a different type ... the result is static_cast<cv T2*>(static_cast<cv void*>(v))
if both T1 and T2 are standard-layout types ...
假设我有一个基本 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
不包含任何数据成员
Is the C-style cast bar* b = (bar*)(f) defined?
C 风格的转换总是有效的,这就是为什么它们是所有转换中最差的。对于非多态 类,您可能希望使用 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_cast
、const_cast
、static_cast
、reinterpret_cast
、C 风格转换。
我同意 iammilind 的 static_cast
相同,但未定义。
Standard(链接文档实际上是草稿,但对大多数用途来说无关紧要)在第 5.2.9 节中说 "the result of the cast is undefined",它描述了 static_cast
。
但是,由于您的 struct bar
没有数据成员,因此它是 标准布局 class,并且 布局兼容 与 struct FOO
。因此,您可以将指针指向 void*
,然后指向 foo*
:
bar* b = (bar*)(void*)f
这在 c++ 中更好地表示为 reinterpret_cast
:
bar* b = reinterpret_cast<bar*>(f)
这在第 5.2.10 节中有描述:
An object pointer can be explicitly converted to an object pointer of a different type ... the result is
static_cast<cv T2*>(static_cast<cv void*>(v))
if both T1 and T2 are standard-layout types ...