Normally, in a typed language, the dispatch mechanism will be performed based on the type of the arguments (most commonly based on the type of the receiver of a message). This might be dubbed 'per-type dynamic dispatch'. Languages with weak or no typing systems often carry a dispatch table as part of the object data for each object. This allows instance behaviour as each instance may map a given message to a separate method.

动态分发:选择哪个对象来执行。

In computer sciencedynamic dispatch is the process of selecting which implementation of a polymorphic operation (method or function) to call at run time. It is commonly employed in, and considered a prime characteristic of, object-oriented programming (OOP) languages and systems.[1]

Object-oriented systems model a problem as a set of interacting objects that enact operations referred to by name. Polymorphism is the phenomenon wherein somewhat interchangeable objects each expose an operation of the same name but possibly differing in behavior. As an example, a File object and a Database object both have a StoreRecord method that can be used to write a personnel record to storage. Their implementations differ. A program holds a reference to an object which may be either a File object or a Database object. Which it is may have been determined by a run-time setting, and at this stage, the program may not know or care which. When the program calls StoreRecord on the object, something needs to decide which behavior gets enacted. If one thinks of OOP as sending messages to objects, then in this example the program sends a StoreRecord message to an object of unknown type, leaving it to the run-time support system to dispatch the message to the right object. The object enacts whichever behavior it implements.[2]

A language may be implemented with different dynamic dispatch mechanisms. The choices of the dynamic dispatch mechanism offered by a language to a large extent alter the programming paradigms that are available or are most natural to use within a given language.

Normally, in a typed language, the dispatch mechanism will be performed based on the type of the arguments (most commonly based on the type of the receiver of a message). This might be dubbed 'per-type dynamic dispatch'. Languages with weak or no typing systems often carry a dispatch table as part of the object data for each object. This allows instance behaviour as each instance may map a given message to a separate method.

Some languages offer a hybrid approach.

Dynamic dispatch will always incur an overhead so some languages offer static dispatch for particular methods.

C++ implementation[edit]

C++ uses early binding and offers both dynamic and static dispatch. The default form of dispatch is static. To get dynamic dispatch the programmer must declare a method as virtual.

C++ compilers typically implement dynamic dispatch with a data structure called a virtual table (vtable) that defines the message-to-method mapping for a given class (C++ as such has no notion of a vtable). Instances of that type will then store a pointer to this table as part of their instance data. This is complicated when multiple inheritance is used. Since C++ does not support late binding, the virtual table in a C++ object cannot be modified at run-time, which limits the potential set of dispatch targets to a finite set chosen at compile time.

Type overloading does not produce dynamic dispatch in C++ as the language considers the types of the message parameters part of the formal message name. This means that the message name the programmer sees is not the formal name used for binding.

Go and Rust implementation[edit]

In Go and Rust, a more versatile variation of early binding is used. Vtable pointers are carried with object references as 'fat pointers' ('interfaces' in go, or 'trait objects' in Rust).

This decouples the supported interfaces from the underlying data structures. Each compiled library needn't know the full range of interfaces supported in order to correctly use a type, just the specific vtable layout that they require. Code can pass around different interfaces to the same piece of data to different functions. This versatility comes at the expense of extra data with each object reference, which is problematic if many such references are stored persistently.

Smalltalk implementation[edit]

Smalltalk uses a type-based message dispatcher. Each instance has a single type whose definition contains the methods. When an instance receives a message, the dispatcher looks up the corresponding method in the message-to-method map for the type and then invokes the method.

Because a type can have a chain of base types, this look-up can be expensive. A naive implementation of Smalltalk's mechanism would seem to have a significantly higher overhead than that of C++ and this overhead would be incurred for each and every message that an object receives.

Real Smalltalk implementations often use a technique known as inline caching[3] that makes method dispatch very fast. Inline caching basically stores the previous destination method address and object class of the call site (or multiple pairs for multi-way caching). The cached method is initialized with the most common target method (or just the cache miss handler), based on the method selector. When the method call site is reached during execution, it just calls the address in the cache. (In a dynamic code generator, this call is a direct call as the direct address is back patched by cache miss logic.) Prologue code in the called method then compares the cached class with the actual object class, and if they don't match, execution branches to a cache miss handler to find the correct method in the class. A fast implementation may have multiple cache entries and it often only takes a couple of instructions to get execution to the correct method on an initial cache miss. The common case will be a cached class match, and execution will just continue in the method.

Out-of-line caching can also be used in the method invocation logic, using the object class and method selector. In one design, the class and method selector are hashed, and used as an index into a method dispatch cache table.

As Smalltalk is a reflective language, many implementations allow mutating individual objects into objects with dynamically generated method lookup tables. This allows altering object behavior on a per object basis. A whole category of languages known as prototype based languages has grown from this, the most famous of which are Self and JavaScript. Careful design of the method dispatch caching allows even prototype based languages to have high performance method dispatch.

Many other dynamically typed languages, including PythonRubyObjective-C and Groovy use similar approaches.

https://en.wikipedia.org/wiki/Dynamic_dispatch

Dynamic dispatch mechanisms的更多相关文章

  1. Dynamic dispatch

    Dynamic dispatch动态调度.动态分发 In computer science, dynamic dispatch is the process of selecting which im ...

  2. this inspection detects names that should resolved but don't. Due to dynamic dispatch and duck typing, this is possible in a limited but useful number of cases. Top-level and class-level items are sup

    输入第一行代码:import logging;logging.basicConfig(level==logging.INFO) 提示:this inspection detects names tha ...

  3. 【PyCharm编辑器】之无法导入引用手动新建的包或类,报:This inspection detects names that should resolve but don't. Due to dynamic dispatch and duck typing, this is possible in a limited but useful number of cases.

    一.现象描述 如下图所示,手动新建个类包calculator.py,想在test.py文件引用它,发现一直报红线,引用失败 Unresolved reference 'calculator' less ...

  4. Increasing Performance by Reducing Dynamic Dispatch

    https://developer.apple.com/swift/blog/?id=39 Increasing Performance by Reducing Dynamic Dispatch Li ...

  5. swift -Dynamic Dispatch

    These instructions perform dynamic lookup of class and generic methods. The class_method and super_m ...

  6. Only Link: What's the difference between dynamic dispatch and dynamic binding

    http://stackoverflow.com/questions/20187587/what-is-the-difference-between-dynamic-dispatch-and-late ...

  7. 【Python】This inspection detects names that should resolve but don't. Due to dynamic dispatch and duck

    情况一:导包import时发生错误,请参考这两位 https://blog.csdn.net/zhangyu4863/article/details/80212068https://www.cnblo ...

  8. Which dispatch method would be used in Swift?-Existential Container

    In this example: protocol MyProtocol { func testFuncA() } extension MyProtocol { func testFuncA() { ...

  9. Which dispatch method would be used in Swift?

    In this example: protocol MyProtocol { func testFuncA() } extension MyProtocol { func testFuncA() { ...

随机推荐

  1. 手动实现aop编程

    手动实现aop编程(运用代理模式实现) aop:aspect object programming 功能:让关注点与业务代码分离 关注点:重复代码就叫做关注点 切面:关注点形成的类,就叫切面(类) 面 ...

  2. rm -fr删除不了文件

    向各位求教:一个阿里的 ecs服务器,放网站的.估计被挂马了,其中网站下的一个文件index.html,被篡改,想删除,但是删除不了. ls -l 结果:-r--r--r--  1 www  www  ...

  3. java中String和int的互相转化

    1. String 转 int 方式1:Integer.parseInt(); 方式2: Integer.valueOf(myStr).intValue(); 2.  int 转String 方式1: ...

  4. TensorFlow实战学习笔记(14)------VGGNet

    一.VGGNet:5段卷积[每段有2~3个卷积层+最大池化层][每段过滤器个数:64-128-256-512-512] 每段的2~3个卷积层串联在一起的作用: 2个3×3的卷积层串联的效果相当于一个5 ...

  5. [USACO17JAN]Promotion Counting

    线段树合并. 正解好像不是线段树合并,但是出于练手的目的写了线段树合并. 大概就是对于左右子树,如果有一个为空,返回非空的,如果都不为空,就把这两个整合到一起就行了. #include <ios ...

  6. java实现根据起点终点和日期查询去哪儿网的火车车次和火车站点信息

    本文章为原创文章,转载请注明,欢迎评论和改正. 一,分析 之前所用的直接通过HTML中的元素值来爬取一些网页上的数据,但是一些比较敏感的数据,很多正规网站都是通过json数据存储,这些数据通过HTML ...

  7. 干货:鲜为人用的MySQL高级特性与玩法!

    上一篇文章<万字总结:学习MySQL优化原理,这一篇就够了!>文末给大家留有两个开放的问题: 有非常多的程序员在分享时都会抛出这样一个观点:尽可能不要使用存储过程,存储过程非常不容易维护, ...

  8. js面向对象编程: js类定义函数时prototype和this差别?

    在面向对象编写js脚本时,定义实例方法主要有两种 例如以下: function ListCommon2(afirst) { var first=afirst; this.do1=function () ...

  9. CC2540 与 CC2541 差别 1

    CC2540 的 1234 PIN 是 USB 功能,4 PIN 是 USB 的电压输入引脚. CC2541 没有 USB 功能.它的 1234 PIN 是 I2C 功能,为了与 CC2540 引脚兼 ...

  10. Java——动态代理

    在静态代理中,我们在调用target类的时候,都是先拿到proxy类.由于proxy类中将target类作为了成员变量,而且跟target类继承了一样的接口,具有同样的方法,所以,在proxy类中.通 ...