双重派发 双重委派 双派发 double dispatch
参考自《c++高级编程》
解决的问题:
在多态时,初始化需要明确接口的实际类型:
Animal animal= bear();
animal.move();
这个animal指针指向真正的实例化类,调用的是animal接口里的方法。编译时可以通过。
这个是运行时多态!!!
如果确定类型时需要两个,甚至多个类型确认,就会有问题。
比如 animal.eats( Animal a)。
编译器只能重载!!!,参数是个基类Animal 类型。而我们在实现中没有这个方法,无法找到成员函数实现:bool eats( Animal a);
这是没有意义的。熊吃动物吗?只有知道具体的才行,而编译器看到 Animal参数只会去找对应的函数实现。
熊的实现一般如下:
class Bear : Animal{
bool eats( Cat cat);
bool eats( Dog cat);
bool eats( Animal a);//这个没有
};
可以看到没有 eats(Animal a)这个成员函数。因此会导致编译错误。
a是个基类类型,编译器无法判定这个函数重载的是哪个:是dog,还是Cat。
多态只有在运行时才能体现出来。
第一种方法解决:
既然编译器找不到 eats(Animal a) 的实现。在Animal接口中添加实现。
class Animal: Animal{
bool eats( Animal a){
}
}
这样就可以通过编译了。
这时用 a.eatenBy(*this),a是运行行多态,可以确定类型。*this也是具体实现,可以得到类型。即双分派。 animal.eats这个是第一个动态;a.eatenBy是第二次。
第二种,采用奇异模板 CRTP
将子类作为模板参数传给基类,让基类把参数强制cast。
第三种,c++23
1//// Before 2// CRTP 3template <class Derived> 4struct Base { 5 void foo() { 6 auto& self = *static_cast<Derived*>(this); 7 self.bar(); 8 } 9}; 10 11struct Derived : Base<Derived> { 12 void bar() const { 13 std::cout << "CRTP Derived\n"; 14 } 15}; 16 17//////////////////////////////////////////// 18//// After 19// Deducing this 20struct Base { 21 template <class Self> 22 void foo(this Self& self) { 23 self.bar(); 24 } 25}; 26 27struct Derived : Base { 28 void bar() const { 29 std::cout << "Deducing this Derived\n"; 30 } 31};
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
2018-12-17 Python之——CentOS 6.5安装Python2.7.14