将指针指向类的第一个成员是非法的? [英] is cast a pointer points-to-class to it's first member illegal?
问题描述
我在项目中看到一些奇怪的代码,如下所示.我对其进行了测试并获得了正确的答案.但是我认为这是非法的,有人可以向我解释吗?
I see some strange code in our project like follows.I test it and get the right answer.But I think it is illegal,Can anyone explain this to me?
class Member
{
public:
Member():
a(0),b(1)
{}
int a;
int b;
};
// contains `Member` as its first member
class Container
{
public:
Container():
c(0),d(0)
{}
Member getMemb(){return fooObject;}
Member fooObject;
int c;
int d;
};
以及我们如何使用它:
int main()
{
auto ctain = new Container;
auto meb = (Member *)ctain; // here! I think this is illegal
cout << "a is " << meb->a << ", b is" << meb->b << endl;
return 0;
}
但是我得到正确的答案,a是0,b是1.这只是巧合吗?我还指出,如果fooObject
不是第一个成员,我会得到一个错误的答案.
but I get the right answer, a is 0 and b is 1.Is this just a coincidence?I also noted that if fooObject
is not the first member, I will get a wrong answser.
推荐答案
该代码段是合法的. C样式强制转换(Member*)
在这里实际上是reinterpret_cast
.来自 [basic.compound]
The snippet is legal. The C style cast (Member*)
here is effectively a reinterpret_cast
. From [basic.compound]
如果满足以下条件,则两个对象
a
和b
是指针可互换的:
Two objects
a
andb
are pointer-interconvertible if:
-
它们是同一对象,或者
they are the same object, or
一个是联合对象,另一个是该对象的非静态数据成员,或者
one is a union object and the other is a non-static data member of that object, or
一个是标准布局类对象,另一个是该对象的第一个非静态数据成员,或者,如果该对象没有非静态数据成员,则是该对象的第一个基类子对象或[...]
one is a standard-layout class object and the other is the first non-static data member of that object, or, if the object has no non-static data members, the first base class subobject of that object, or [...]
如果两个对象是指针可互换的,则它们具有相同的地址,并且可以通过reinterpret_cast
从指向另一个的指针获得指向一个的指针.
If two objects are pointer-interconvertible, then they have the same address, and it is possible to obtain a pointer to one from a pointer to the other via a reinterpret_cast
.
应特别注意确保它确实是标准布局类型,可能带有static_assert(std::is_standard_layout_v<Container>)
Special care should be taken to make sure it is indeed a standard layout type, possibly with a static_assert(std::is_standard_layout_v<Container>)
另一方面,如果您只写了auto meb = &ctain.fooObject;
On the other hand, you could sidestep this entire fiasco if you just wrote auto meb = &ctain.fooObject;
这篇关于将指针指向类的第一个成员是非法的?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!