向下转换时static_cast悬挂参考

时间:2018-11-28 11:37:37

标签: c++ c++11 language-lawyer

以下代码是正确的还是由于悬挂的引用而导致未定义的行为以及为什么它正确?

class A {};
class B : public A {};

B& f(A& a) {
  // Dangling reference here?
  return static_cast<B&>(a);    
}

int main()
{
  A a;
  B& b = f(a);
}

2 个答案:

答案 0 :(得分:2)

这是未定义的行为,但不是因为悬挂的引用。当static_cast实际上不是未定义的子行为时,使用 B& b = f(a); // Casts `A` type to `B` incorrectly 将对象从父类转换为子类的行为:

{{1}}

请参阅相关标准报价here

答案 1 :(得分:0)

悬空引用是对不再存在的对象的引用。 在您的代码示例中,没有问题,因为A与B处于同一范围内,因此引用始终有效。

现在,以修改后的示例为例,在创建对对象A的引用后,将其删除。实际上,这是一个悬空的引用,删除对象A后会产生未定义的行为。

#include <iostream>

class A {
public:
  int m;
};
class B : public A {};

B& f(A& a) {
  return static_cast<B&>(a);
}

int main()
{
  A *a = new A();
  a->m = 42;
  B& b = f(*a);
  std::cout << b.m << std::endl; // Valid                                       
  delete a; // Dangling reference created here                                
  std::cout << b.m << std::endl; // Undefined behavior                          
}