早教吧 育儿知识 作业答案 考试题库 百科 知识分享

关于C#虚函数的问题希望高手指教,不要搜索来的大堆资料,那些都看过了。谢谢。虚函数用来实现在派生类中对方法的重写。但是使用new修饰符一样可以达到这个效果呢。比如:class

题目详情
关于C# 虚函数 的问题希望高手指教,不要搜索来的大堆资料,那些都看过了。 谢谢。 虚函数用来实现在派生类中对方法的重写。 但是 使用new修饰符一样可以达到这个效果呢。 比如: class BaseClass { public void NVMeth() { Console.WriteLine("调用了基类BaseClass的NVMeth"); } public virtual void VMeth() { Console.WriteLine("调用了基类BaseClass的VMeth"); } } class InClass : BaseClass { new public void NVMeth() { Console.WriteLine("调用了派生类InClass的NVMeth"); } public override void VMeth() { Console.WriteLine("调用了派生类InClass的VMeth"); } } 两种方法都实现了对基类方法的调用,那么他们有什么区别呢。虚函数的存在意义在于哪点呢。 主函数中如果这样 InClass InObj = new InClass(); BaseClass BaseObj = InObj; BaseObj.NVMeth(); BaseObj.VMeth(); 得到的结果是: 调用了基类BaseClass的NVMeth 调用了派生类InClass的VMeth 书上关于这个的解释是: 由于运行时多态,执行语句InClass InObj=new InClass();时产生的对象InObj中已有虚方法的代码,执行语句BaseClass BaseObj=InObj;时虚方法代码一起赋值给了BaseObj变量。 那么为什么 NVMeth 的代码没有一起赋值给BaseObj变量呢 ?
▼优质解答
答案和解析
如果你有一定c++基础,知道指针含义,和对象在内存中的分配状况就很容易理解了 对象在new的时候会在内存的堆。他的结构就像下面 InClass InObj = new InClass(); inobj---->内存堆中的一个指针 对象函数表 //对象函数表,每一个对象都有一个对象函数表,已标示对象的每个方法函数的入口地址 方法NVMeth()相对头部偏移xx距离 方法VMeth() 相对头部偏移 虚函数VMeth() 重载,实际上是把VMeth() 相对头部偏移的那个量给改动了 方法NVMeth()没有被重载所以那个偏移量还是原来的 BaseClass BaseObj = InObj; 这里发生转换,因为引用对象,所以实质是把对象的指针传给了BaseObj,但是他的函数表还是inobj的函数表 因为方法NVMeth()相对头部偏移没有改变,所以系统找到了基类的函数,而 方法 VMeth() 由于被重载了所以他的那个偏移量变了,所以他找到的是修改后的函数入口 我这里讲的有关对象的底层实现机制,需要有一定c++知识才看的明白,如果你看不懂的话 请参考下面几本书 《c和指针》该书已绝版,不过网上有电子版可以看 《深入c++对象模型》 《深入浅出mfc》的前面几章有关mfc中对象实质部分
看了关于C#虚函数的问题希望高手指...的网友还看了以下: