zoukankan      html  css  js  c++  java
  • 继承和多态在C#中的实现

    刚开始写blog,最近要考试就先把以前写的一些读书心得和经验总结记下,当然难免有错,欢迎大家指正。

    与调用普通方法不同,当CLR遇到vitual 方法的时候,会使用callvirt (IL)命令与普通的call(IL)不同callvirt除了第一句外(把this送到ecx寄存器),还有第二句,把this对象的type handle送到了eax寄存器中。另外callvirt还会先检查this对象是否为null
    call
    mov ecx, esi
    call dword ptr ds:[352108h]

    callvirt
    move ecx, esi
    move eax, dword ptr [ecx]
    call dword ptr [eax + 38h]

    其中最关键的就是那个offset, 对于每个virtual方法,有以下的属性 

     


    这张图是各个关键字所对应的属性 
         
     

    如果新方法具有newslot的属性(比如使用了virtual关键字),那么新方法的offset就会至少在原类型的virtual method 的offest最大值上+1,如果不是newslot那么就会在base类型的virtual method table中找到与该方法同名的方法,并重用原类型的那个virtual method offset。如果找不到,就会新建一个。简而言之就是有则使用原来的offset,没有就扩大virtual method table,使用新增的offset。这样在不同类型中同样的方法在VMT中的offset是相同的,不同的是this指针的地址也就是eax中的内容,这样就保证了第三句call dword ptr [eax + 38h] 的执行会调用到正确的方法,多态也就得到了实现。

     

    注意从上图可以看出override的方法也是vitual method,只不过它的newslot0,说明不需要为它寻找新的空间。



    以上是当时看Essential。NET记的体会。很简陋。希望能看出点东西。

  • 相关阅读:
    mybatis集成spring
    静态代码块-普通代码块-构造代码块(好多图)
    Mybatis generator(复制粘贴完成)
    委派模式和适配器模式
    mysq--索引模块
    谈谈TCP的四次挥手
    说说TCP的三次握手
    网络基础知识
    java的IO机制
    std::bind接口与实现
  • 原文地址:https://www.cnblogs.com/idior/p/76288.html
Copyright © 2011-2022 走看看