c++ static_cast 在运行时到虚拟基

问题描述 投票:0回答:1

假设我们有这样的代码:

struct Granny {
  int g;
};
struct Mom : virtual Granny {
  int m;
};
struct Son : Mom {
  int s;
};

int main() {
  int x;
  std::cin >> x;
  Mom* mom = (x ? new Son : new Mom);
  Granny* granny = static_cast<Granny*>(mom);
}

类不是多态的,所以 Granny 没有 vtable。现在,根据x,mom指针下可以有不同的内存布局。因此,子对象 Granny 将从对象开始移动 16 或 12 个字节。

问题:是 static_cast 而不是“简单地移动指针”编译在“在 mom 对象中取消引用 vptr(vtable),然后查看某个索引以找到虚拟偏移量,然后最后按此偏移量移动指针”?那么,static_cast 会有 2 个额外的运行时操作吗?如果没有,请解释一下发生了什么。

c++ runtime vtable static-cast virtual-inheritance
1个回答
0
投票

您可以将这两种情况放入编译器资源管理器中:

Granny* from_Son(Son* x) { return static_cast<Granny *>(x); }
Granny* from_Mom(Mom* x) { return static_cast<Granny *>(x); }

编译为以下三个指令(带有错误检查):

        mov     rax, QWORD PTR [rdi]    
        add     rdi, QWORD PTR [rax-24]
        mov     rax, rdi

在此片段中,

rdi
x
[rdi]
是您的 vtable,因此
Granny
的偏移量存储在 vtable 之前的 24 个字节处。

© www.soinside.com 2019 - 2024. All rights reserved.