我在某个地方找到了一些代码并决定在汇编中吐出来试图找到差异.
#include <iostream>
class A {
public:
void f() const { std::cout << "A::f()" << std::endl; }
};
class B {
public:
void f() const { std::cout << "B::f()" << std::endl; }
};
int main()
{
A a ;
B b ;
a.f() ;
b.f() ;
}
Run Code Online (Sandbox Code Playgroud)
-
#include <iostream>
class base {
public:
virtual void f() const = 0 ;
virtual ~base() {}
};
class A : public base {
public:
virtual void f() const { std::cout << "A::f()" << std::endl; }
};
class B : public base {
public:
virtual void f() const { std::cout << "B::f()" << std::endl; }
};
void dispatch(const base & x) {
x.f();
}
int main() {
A a ;
B b ;
dispatch(a) ;
dispatch(b) ;
}
Run Code Online (Sandbox Code Playgroud)
我正在看这个类似的问题(如何判断一个程序是否通过查看程序集来使用动态调度)并试图在程序集中找到它,但是我不清楚.
这是两个程序的差异文件(http://www.diffchecker.com/b9y0v3ps).有人可以指出动态调度发生的位置,或许可以解释一下发生了什么以及两者之间的区别是什么?
从您链接到的程序集,非虚拟分派如下:
53 call _ZNK1A1fEv
Run Code Online (Sandbox Code Playgroud)
直接调用该函数.
虚拟调度如下:
53 mov EAX, DWORD PTR [EBP - 4]
54 mov ECX, DWORD PTR [EAX]
56 call DWORD PTR [ECX]
Run Code Online (Sandbox Code Playgroud)
从对象加载vtable的地址,然后从vtable加载函数地址,然后间接调用该函数.