gpt4 book ai didi

c++ - 是否存在将实际 Base 向下转换为 Derived 的情况?

转载 作者:可可西里 更新时间:2023-11-01 16:35:34 24 4
gpt4 key购买 nike

在一般情况下,从(动态)Base 向下转换到派生类之一 Derived 是(当之无愧的)未定义行为

明显的 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值不一致的问题,其中包含垃圾值。因此,标准没有定义这些条件下的沮丧行为是有道理的。

不那么明显的天真案例

但我很想知道在特定情况下是否会对这条规则做出一些让步?例如:

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 ?

在这里我们可以很容易地想象编译器在做正确的事情。 但是从标准的角度来看,它还是undefined吗?

编辑:static_cast 是用于说明目的的随机选择,如果与其他 Actor 合作也很有趣!

最佳答案

好吧,我可能会因为这个答案而被撕成碎片......

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

在这些条件下,即使是 UB,您的 Actor 也不会造成任何麻烦。据其中一位消息人士称,至少可以安全地进行一次

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 的能力。

关于c++ - 是否存在将实际 Base 向下转换为 Derived 的情况?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20263888/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com