现在的位置: 首页 > 综合 > 正文

c#和Cpp的虚拟函数表的区别

2013年09月20日 ⁄ 综合 ⁄ 共 1954字 ⁄ 字号 评论关闭
文章目录

前不久看到一文章:

http://zhenyulu.cnblogs.com/archive/2006/04/18/377705.html

C#接口

(未完整摘录)

本文将通过以下四个案例来分析C#中的接口究竟是如何工作的。

1、公有方法实现接口方法

尽管C#在定义接口时不用指明接口方法的访问控制方式,但默认接口方法均为public型(这可以从反编译的IL代码中看到)。下面是使用Reflector查看的接口IL代码

.class private interface abstract auto ansi IControl
{
   .method public hidebysig newslot abstract virtual instance void Paint() cil managed
   {
   }
}

实现接口的类需要实现所有接口方法。通常情况下,接口的实现方法也为public型。如下案例:

using System ;
interface IControl 
{
   void Paint();
}
public class EditBox: IControl 
{
   public void Paint() 
   {
      Console.WriteLine("Pain method is called!");
   }
}
class Test 
{
   static void Main() 
   {
      EditBox editbox = new EditBox(); 
      editbox.Paint();
      ((IControl)editbox).Paint();
   }
}

程序的执行结果为:

Pain method is called!
Pain method is called!

接口就好像是关系型数据库中的一对多表,一个接口对应多个接口方法,每个接口方法又对应虚拟方法表(VMT)中的某个公有或私有方法。上面代码在内存中的镜像可由下图描述:

从图中我们可以看到直接对Paint方法的调用以及通过接口对Paint方法的调用。可见通过接口对方法进行调用需要多出一道转换工作,因此执行效率不如直接调用。

2、私有方法不能实现接口方法

如果想将接口方法直接实现为私有方法是办不到的。下面的EditBox的代码中Paint方法没有特殊说明,默认为private,导致代码无法执行:

using System ;
interface IControl 
{
   void Paint();
}
public class EditBox: IControl 
{
   void Paint() 
   {
      Console.WriteLine("Pain method is called!");
   }
   public void ShowPaint()
   {
      this.Paint();
      ((IControl)this).Paint();
   }
}
class Test 
{
   static void Main() 
   {
      EditBox editbox = new EditBox(); 
      editbox.ShowPaint();
   }
}

程序在编译时将显示如下编译错误:““EditBox”不会实现接口成员“IControl.Paint()”。“EditBox.Paint()”或者是静态、非公共的,或者有错误的返回类型。”

为什么会这样呢?如图:

这是由于接口规范中的方法默认的访问权限是public,而类中的默认访问权限是default,也就是说private,因此导致权限范围收缩,两者权限并不相同,所以必须将类的权限调整为public才可以使上面的代码得以执行。

 

然后式了下 cpp的vtable规则..

#include <iostream>
using namespace std;

class IControl
{
public:
   virtual void Paint()  =0;
};

class EditBox: public IControl
{
private:
   void Paint()
   {
      cout<<"sads"<<endl;
   }
public:
 void ShowPaint()
   {
      this->Paint();
      ((IControl*)this)->Paint();
   }
};

int main(int argc, char* argv[])
{
 EditBox *editbox = new EditBox();
      editbox->ShowPaint();
 return 0;
}

在 cpp下是恰当的..符合我得预期.. 

cpp vatble的 重写没有访问权限的控制.

抱歉!评论已关闭.