mai*_*mai 4 c++ pointers casting
我在我们的项目中看到一些奇怪的代码,如下所示。我测试它并得到正确的答案。但我认为这是非法的,谁能给我解释一下?
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;
};
Run Code Online (Sandbox Code Playgroud)
以及我们如何使用它:
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;
}
Run Code Online (Sandbox Code Playgroud)
但是我得到了正确的答案,a是0,b是1。这只是巧合吗?我还注意到如果fooObject不是第一个成员,我会得到错误的答案。
该片段是合法的。这里的C 风格转换(Member*)实际上是一个reinterpret_cast. 来自[basic.compound]
两个对象
a并且b在以下情况下是指针可转换的:
它们是同一个对象,或者
一个是联合对象,另一个是该对象的非静态数据成员,或
一个是标准布局类对象,另一个是该对象的第一个非静态数据成员,或者,如果该对象没有非静态数据成员,则是该对象的第一个基类子对象,或 [... ]
如果两个对象是指针可互转换的,则它们具有相同的地址,并且可以通过 a 从指向另一个的指针获取指向一个的指针
reinterpret_cast。
应特别注意确保它确实是标准布局类型,可能带有static_assert(std::is_standard_layout_v<Container>)
另一方面,如果你只是写了,你可以避开整个惨败 auto meb = &ctain.fooObject;