c中动态调度的规则是什么?

前端之家收集整理的这篇文章主要介绍了c中动态调度的规则是什么?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我不知道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代码相同的行为;此处不会更改)

解决方法

对于C,当你做b-> op(2.0,4.0);编译器在B中查找一个可以调用方法(int x,double y)并使用它.如果子类中的任何方法可以处理该调用,它不会在超类中查找.这被称为方法隐藏,即. op(double,double)是隐藏的.

如果要使其选择(双x,双y)版本,则需要使B中的函数可见,B内有以下声明:

using A::op;

Further explanation of the rules

猜你在找的C&C++相关文章