从(对基对象的基引用)到(派生类引用)的静态转换

Lea*_*Cpp 1 c++ downcast c++11

main下面的函数中,第一个static_cast是有效的,因为我试图将一个(对Derived1类的基类引用)转换为派生引用但是为什么第二个转换打印带有这些值,虽然它打印了垃圾值d2.y,但我认为它应该是警告或编译错误。对基对象的基引用如何选择派生类的值(d2.y在这种情况下,我也可以为其分配一个值)

有人可以解释一下在这两种情况下会发生什么。

class Base1
{
 public:
  Base1()
  {
    x = 999;
  }
 int x;
};

class Derived1: public Base1
{
  public:
  Derived1()
 {
    y = 1000;
 }
  int y;
};

int main()
{
 Derived1 d;
 std::cout << d.x << " " << d.y << std::endl;
 Base1& b = d;
 Base1 b1;

 Base1 & b2 = b1;

 Derived1& d1 = static_cast<Derived1&>(b);
 Derived1& d2 = static_cast<Derived1&>(b2);

 std::cout << d1.x << " " << d1.y << std::endl;
 std::cout << d2.x << " " << d2.y << std::endl;

 return 0;     
}
Run Code Online (Sandbox Code Playgroud)

xax*_*xon 5

Astatic_cast是您对编译器的一个承诺,即基类确实是一个派生类——计算机无需再次检查。您告诉编译器,作为程序员,您知道一些编译器无法知道的事情,哪些可以保证这是真的。因此,当 CPU 发出指令以访问派生类型成员应该在的内存地址处的值时,它会进入一些可以包含几乎任何内容的内存,就像你告诉它的那样。

除了非常简单的情况外,编译器无法知道对基类型的引用真正具有什么。这就是 dynamic_cast 存在的原因(但它需要额外的信息——vtable——来检查)。

static_cast如果两种类型不可能相关,则会导致编译时错误,但如果它们在同一继承链中,您可以使用无效的static_cast.

当您开始将 C/C++ 类型视为内存偏移的简单定义时,许多行为和语法要求开始变得更有意义。