在 C++ 中我们需要 double dispatch/visitor 到底发生了什么
What exactly happened that we need double dispatch/visitor in c++
我理解解决方案的实现和双重 dispatch/visitor 模式,但是我不明白在编译时和 运行-我们需要这个模式时会发生什么。
例如这段代码:
#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,机器代码?)
你说得太深了,简单多了。
C++ 虚函数根据 单个 参数 this
的类型启用动态调度。双重调度,顾名思义,就是根据两个参数的类型进行动态调度。由于该语言不提供此功能,Visitor 模式只是使用内置的单一调度两次,依次使用每个动态参数作为this
。
您可以想象,通过继续这个抢椅子游戏,直到所有动态参数都 this
一次并在最终调用之前正确分配,您可以实现执行三次或更多次分配的访客。
我理解解决方案的实现和双重 dispatch/visitor 模式,但是我不明白在编译时和 运行-我们需要这个模式时会发生什么。
例如这段代码:
#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,机器代码?)
你说得太深了,简单多了。
C++ 虚函数根据 单个 参数 this
的类型启用动态调度。双重调度,顾名思义,就是根据两个参数的类型进行动态调度。由于该语言不提供此功能,Visitor 模式只是使用内置的单一调度两次,依次使用每个动态参数作为this
。
您可以想象,通过继续这个抢椅子游戏,直到所有动态参数都 this
一次并在最终调用之前正确分配,您可以实现执行三次或更多次分配的访客。