加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 是否会定义将实际基准转换为衍生的情况?

发布时间:2020-12-16 03:44:29 所属栏目:百科 来源:网络整理
导读:在一般情况下,它是(一个非常应得的)未定义行为从(动态)基础到推导类之一派生 明显的UB class Base{public: virtual void foo() { /* does something */} int a;}class Derived : public Base{public: virtual void foo() { /* does something different */}
在一般情况下,它是(一个非常应得的)未定义行为从(动态)基础到推导类之一派生

明显的UB

class Base
{
public:
    virtual void foo()
    { /* does something */}

    int a;
}

class Derived : public Base
{
public:
    virtual void foo()
    { /* does something different */}

    double b;
}

Base obj;
Derived derObj = *static_cast<Derived *>(&obj);  // <- here come the demons

在编译器的当前实现方法中,显然至少存在Vtable和b中包含垃圾值的值不一致的问题.所以在这些条件下,标准没有定义一个downcast的行为是有道理的.

不太明显的天真的情况

但是我很好奇知道在具体情况下是否有这样的规定呢?
例如:

class Base
{
public:
    void foo()
    { /* does something */}

    int a = 1;
    double b = 2.;
}

class DerivedForInt : public Base
{
    int getVal()
    { return a }
}

Base obj;
DerivedForInt derObj = *static_cast<DerivedForInt *>(&obj);  // <- still an UB ?

在这里我们可以很容易地想象编译器做正确的事情.但从标准的角度来看,还不清楚?

编辑:static_cast是用于说明目的的随机选择,如果与其他演员一起工作也很有意思!

解决方法

好的,我可能会为这个答案碎片

显然,正如其他答案所说,这是未定义的行为,如标准中所述.但是,如果您的Base类具有标准布局,并且DerivedForInt类不添加新数据成员,则它将具有相同的(标准)布局.

在这些条件下,即使是UB,你的演员也不应该出现任何麻烦.据其中一个消息来源,至少可以做到安全

DerivedForInt *derived = reinterpret_cast<DerivedForInt*>(&base.a);

资料来源:

What are Aggregates and PODs and how/why are they special?

PODs and inheritance in C++11. Does the address of the struct == address of the first member?

从第二个链接:

Here’s the definition,from the standard section 9 [class]:

A standard-layout class is a class that:

  • has no non-static data members of type non-standard-layout class (or array of such types) or reference,
  • has no virtual functions (10.3) and no virtual base classes (10.1),
  • has the same access control (Clause 11) for all non-static data members,
  • has no non-standard-layout base classes,
  • either has no non-static data members in the most derived class and at most one base class with non-static data members,or has no base classes with non-static data members,and
  • has no base classes of the same type as the first non-static data member.


然后保证您想要的属性(第9.2节[class.mem]):

A pointer to a standard-layout struct object,suitably converted using a reinterpret_cast,points to its initial member (or if that member is a bit-field,then to the unit in which it resides) and vice versa.

这实际上比旧的要求更好,因为通过添加非平凡的构造函数和/或析构函数来重新解释_cast的能力不会丢失.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读