我了解解决方案的实现以及双重分发/访问者模式,但是我不了解在编译时和运行时我们需要这种模式会发生什么。
例如此代码:
#include <iostream>
class A {
public:
};
class B : public A {
};
class F {
public:
virtual inline void operator()(const A&) const noexcept {
std::cout << "FxA" << std::endl;
}
virtual inline void operator()(const B&) const noexcept {
std::cout << "FxB" << std::endl;
}
};
class G : public F {
public:
virtual inline void operator()(const A&) const noexcept {
std::cout << "GxA" << std::endl;
}
virtual inline void operator()(const B&) const noexcept {
std::cout << "GxB" << std::endl;
}
};
void by_const_ref(const F& f, const A& a) {
f(a);
}
int main() {
by_const_ref(F(), A());
by_const_ref(F(), B());
by_const_ref(G(), A());
by_const_ref(G(), B());
return 0;
}
在没有双调度的情况下,对by_const_ref的第二次和第四次调用不会将B()解析为A对象。
本文摘自https://en.wikipedia.org/wiki/Double_dispatch#Double_dispatch_in_C++,我了解它涉及名称修饰,运行时的编译时以及vtable解析,但是我没有找到确切的方法。
对于名称处理部分,我查看了已编译的对象,但没有发现任何特殊之处。
对于vtable,我将其与g ++ -fdump-lang-class一起转储了,看起来好像那里也没有太多信息。
因此,我的要求。我想了解到底发生了什么,以及可能如何检查这种行为(使用nm等工具,检查vtable,机器代码?)
答案 0 :(得分:4)
你太深了,这很简单。
C ++虚函数基于单个参数this
的类型启用动态调度。顾名思义,双重调度是基于两个参数类型的动态调度。由于该语言没有提供此功能,因此,Visitor模式仅使用内置的一次调度两次,并将每个动态参数依次用作this
。
可以想象,通过继续进行此音乐椅游戏,直到所有动态参数都被this
一次并在最终通话之前被正确调度为止,来实现访客执行三重调度或更多操作。