【问题标题】:Derived class returns allocated base class instance派生类返回分配的基类实例
【发布时间】:2020-04-10 14:54:16
【问题描述】:

以下在 C++ 中是否合法? 派生类正在分配基类并将其转换为派生类。 显然,如果派生(C)有成员,任何通过返回的指针访问成员的人都会失败。但即使没有派生成员 - 这是合法的吗? UB?

struct B { int a; };
struct C : B { 
   static C* get() {
       return static_cast<C*>(new B);
   }
   enum { X, Y,};
};
int main(){
   C* c = C::get();
   return c->X;
}

【问题讨论】:

  • 您提议的演员表是否在此处允许的演员表列表中:en.cppreference.com/w/cpp/language/static_cast - 否?然后违法。我在那儿看不到,但你可以看看。
  • 几乎可以肯定是UB,static_cast到非动态类型感觉就像UB
  • 只是为了说清楚。这出现在我正在执行并发现的代码审查中。正如人们开始指出的那样,我的观点是——这是一个 UB。寻找可以找到实际 std 子句/段落或类似内容的人。谢谢。
  • 这是未定义的行为。在main() 中,指针c 不指向C(它指向B),因此取消引用为C 会产生未定义的行为。
  • 看看那个页面 - 你有没有看到像“除非派生类没有成员”这样的东西?不?那么就没有这样的例外了。

标签: c++ inheritance language-lawyer static-cast


【解决方案1】:

它是UB。标准摘录(重点是我的):

8.2.9 Static cast - bullet 11

类型“pointer to cv1 B”的纯右值,其中 B 是类类型,可以转换为类型“pointer to cv2 D”的纯右值,其中 D 是从 B 派生的类,如果 cv2 相同cv-qualification 与 cv1 相同或更高的 cv-qualification。如果 B 是 D 的虚拟基类或 D 的虚拟基类的基类,或者如果不存在从“指向 D 的指针”到“指向 B 的指针”的有效标准转换 ([conv.ptr]),则程序格式不正确。空指针值转换为目标类型的空指针值。如果“指向 cv1 B 的指针”类型的纯右值指向实际上是 D 类型对象的子对象的 B,则生成的指针指向 D 类型的封闭对象。否则,行为未定义。

【讨论】:

猜你喜欢
  • 1970-01-01
  • 2014-04-27
  • 2013-02-12
  • 2023-03-19
  • 1970-01-01
  • 2011-04-14
  • 1970-01-01
  • 2014-09-29
  • 1970-01-01
相关资源
最近更新 更多