我不知道C中的动态调度是否真的有效.为了说明我的问题,我将从一些
Java代码开始.
class A { public void op(int x,double y) { System.out.println("a"); } public void op(double x,double y) { System.out.println("b"); } } class B extends A { public void op(int x,double y) { System.out.println("c"); } public void op(int x,int y) { System.out.println("d"); } } class C extends B { public void op(int x,int y) { System.out.println("e"); } } public class Pol { public static void main(String[] args) { A a = new C(); B b = new C(); /* 1 */ a.op(2,4); /* 2 */ b.op(2.0,4.0); } }
调用a.op(2,4)将打印“c”,因为确实是编译器:
>查看A类(因为a被声明为类型A的变量)哪个方法最接近于op(int,int),
>找不到一个op(int,int)方法,但是找到方法op(int,double)(使用单个auto-cast int – > double)
>然后修复这个签名.
执行期间,JVM:
>寻找一个方法与签名op(int,double)由编译器固定为C类但没有找到它,
看看C的超级类,即B,
>并最终找到一个方法op(int,double),然后调用它.
同样的原则适用于打印“b”的b.op(2.0,4.0).
现在,考虑C中的等效代码
#include <iostream> class A { public: virtual void op(int x,double y) { std::cout << "a" << std::endl; } virtual void op(double x,double y) { std::cout << "b" << std::endl; } }; class B : public A { public: void op(int x,double y) { std::cout << "c" << std::endl; } virtual void op(int x,int y) { std::cout << "d" << std::endl; } }; class C : public B { public: void op(int x,int y) { std::cout << "e" << std::endl; } }; int main() { A *a = new C; B *b = new C; /* 1 */ a->op(2,4); /* 2 */ b->op(2.0,4.0); delete a; delete b; }
a-> op(2,如Java.但是b-> op(2.0,4.0)再次输出“c”,在那里,我输了.
在C编译和执行过程中应用的规则是什么是动态调度?
(注意,如果您在每个函数前面写入虚拟对象,您将具有与C代码相同的行为;此处不会更改)