将指针指向类的第一个成员是非法的? [英] is cast a pointer points-to-class to it's first member illegal?

查看:85
本文介绍了将指针指向类的第一个成员是非法的?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在项目中看到一些奇怪的代码,如下所示.我对其进行了测试并获得了正确的答案.但是我认为这是非法的,有人可以向我解释吗?

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]

如果满足以下条件,则两个对象ab是指针可互换的:

Two objects a and b 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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆