日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > C# >内容正文

C#

让我们来比较C#,C++和Java之间重写虚函数的区别

發(fā)布時間:2025/3/15 C# 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 让我们来比较C#,C++和Java之间重写虚函数的区别 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

這篇文章比較了C++,C#和Java在面向?qū)ο笾械睦^承和函數(shù)重寫的不同。

介紹


我一直用三種不同的面向?qū)ο蟮恼Z言,這三種語言都很明顯的支持繼承和遲綁定或者虛函數(shù)。我認(rèn)為一篇好的文章當(dāng)我在用Java,c#和C++中切換時他們在語法和內(nèi)定行為的不同地方會提醒我。


背景


我不斷的在切換用C++寫霜凍視頻游戲引擎和用C#寫工具和網(wǎng)頁服務(wù)器。我也用Java寫我的安卓主要的項目(最新的一個是群集智能的螞蟻巢穴模擬器-敬請期待)

同樣我認(rèn)為我要給自己做筆記,在繼承、函數(shù)重寫(虛函數(shù))使用三種不同的語言直接的主要區(qū)別。


使用代碼


可接入性

C++支持共有,保護,和私有繼承。但是無論它做了什么,不要忘了任何的私有成員總是私有的,不能變?yōu)榭山尤氲臑槿魏位A(chǔ)或派生類調(diào)用。

?

Java簡化了繼承并且只允許共有繼承。

?

C#在這個方面仿照了Java。

?

大家都普遍同意在面向?qū)ο笳Z言中通過封裝和其他功能可實現(xiàn)保護和私有繼承,不需要這些其他復(fù)制的置換。


多繼承


現(xiàn)在我們來將一點關(guān)于多繼承。當(dāng)建立了一個類的層級時,C++只用冒號繼承,緊隨其后的是逗號,用來分開其他基類列表。C++是唯一一個支持多繼承的語言,如果你一不小心那將會出現(xiàn)像致命的死亡菱形(DDD)結(jié)構(gòu)這種事情??傮w來說,命的死亡菱形(DDD)是一個設(shè)計,這個設(shè)計是多個同一類是對象的一部分實例。設(shè)想一個類叫Dog,這個Dog繼承了Animal和Pet,并且這個Animal和Pet都繼承了一個叫Printable的類,狗這個實例現(xiàn)在有兩個叫Printable的基類的實例。當(dāng)你在Dog這個類里面改變了這個Printable類的屬性后會發(fā)生什么呢?它是否會改變實例1或?qū)嵗?的屬性呢?等等等。為了避免繼承里面這種復(fù)雜的問題(無論如何,我們通常喜歡類的組合勝過繼承-組合展開是一個原因),C#和Java兩者都不支持多繼承。


接口


多年前,C++還是這個編程大陸的王者時,你可能會用抽象類(一個不能被實例化的類,而且最少包含了一個純虛函數(shù))并且要把所有的純虛函數(shù)定義為一種格式也就是=0。這就意味著你需要在派生類中實現(xiàn)這些功能。這樣就誕生了接口這個定義。在C#和Java中你能操作接口,從而給你類似與多繼承的一種協(xié)定(或者你必須執(zhí)行函數(shù)簽名)

?

C#不僅支持接口(類似與C++里面的抽象類,類中包含了索引的純虛函數(shù))還支持帶有一個或多個存虛函數(shù)的抽象類,并且這些函數(shù)是帶有某種真實的功能。記住接口和抽象類里的函數(shù)必須是公用,這樣就可以在調(diào)用類的時候?qū)λ麄冞M行直接訪問,在接口里面定義私有函數(shù)往往沒有太多意義,誰又能調(diào)用它呢?抽象類中這個類是不能調(diào)用他自己的函數(shù),這是沒有意義的!所以,C#涵蓋了抽象類、接口和具體類這三種。

?

讓我們來看這些用三種編程語言,帶有繼承和接口聲明類的代碼。


C++

class derived : public base, base2 //C++ class definition with 2 public inherited classes


Java

class Derived extends Base implements printable // new derived class that derives from base, and implements the printable contract
C# public interface printable //A contract interface public abstract class baser //A class with one or more abstact functions public class derived : baser, printable //A derived class from baser, it implements the printable interface

虛函數(shù)


面向?qū)ο蟮牧硪粋€方面是多態(tài)。這種方法是一種是在運行是構(gòu)建的,在編譯類型時我們只知道它的層次結(jié)構(gòu),舉一個繼承中衍生類的例子,我們有一個基類型的指針。使用遲綁定調(diào)用這個函數(shù),這個函數(shù)是在運行中被判斷而不是編譯時。這三種語言都支持遲綁定這就是虛函數(shù)。


C++

有一個老舊的思想是默認(rèn)把這個函數(shù)設(shè)置為非純虛函數(shù)。正如待會我說的那樣,如果你有一個基類和一個派生類,他們倆都有一個叫print()的函數(shù),你實構(gòu)建哪種類的實例都沒有關(guān)系,你將在類上調(diào)用函數(shù)這取決你引用或者指針是什么類型,如果你不知道你指向的是什么。用虛函數(shù),你一定要聲明虛函數(shù)(這種層次結(jié)構(gòu)在哪都是非常好的),這是告訴編譯器創(chuàng)建一個虛函數(shù)表,當(dāng)運行是你要查找函數(shù)的地址就會依賴這張表里面。一旦函數(shù)被標(biāo)記成虛函數(shù),實例將會判決到哪調(diào)用你的函數(shù),不再依賴于引用和指針。

Java

Java一項都超級簡單,所有的函數(shù)都是虛函數(shù),不需要任何陳述去告訴運行引擎那些是虛函數(shù),如果一個派生類和基類都聲明了一個叫print的函數(shù),都具有同樣的簽名,那么實例將依賴JRE的決定。超級簡單!除非你不想要這個功能(也許安全是個令人擔(dān)憂的問題比如你不想函數(shù)void?AddMoneyToBankAccount()被重寫),在這種情況下你要標(biāo)記它為常函數(shù),并且不要想著去重寫它!艸!


C#

最后是C#,在C#這里所有函數(shù)默認(rèn)都是非虛函數(shù),不僅僅是這樣,如果你想去重寫一個函數(shù),你得這個在基類上打上虛函數(shù)這個標(biāo)簽,并且重新時也要打上這個前綴標(biāo)簽。你可以做到的,然而,有兩個相同簽名的函數(shù),在繼承關(guān)系里面,并且他們并不是被重寫的關(guān)系,你要給派生類的那個函數(shù)打上“new”?這個標(biāo)簽。你要明確的告訴編譯器,我是故意這么做的。你想隱藏基類函數(shù)的功能,并且這不是虛函數(shù)。但是如果你調(diào)用函數(shù)用的是基類的指針,它將總是調(diào)用基類的函數(shù),即使你指向一個派生類的指針,你所看的這樣的功能是編譯器靜態(tài)鏈接時做的,運行時是動態(tài)的(盡管沒有專門的C#編譯器)

?

最后一些代碼來說明所有的虛函數(shù)和函數(shù)重寫!!


C++ Code

#include "stdafx.h" #include <iostream>using namespace std;class base {public:void hello(){cout << "Base func non-virtual" << endl;}virtual void hello2(){cout <<"Base func virtual"<<endl;} };class derived : public base //C++ class definition with 2 inherited classes { public:void hello(){cout << "Derived func non-virtual" << endl;}virtual void hello2(){cout <<"Derived func virtual"<<endl;}};int main() {cout << "calling function defined in both base and der that is NOT virtual, then calling a function that is virtual" << endl;{cout << "Instance is Derived - Reference is Derived" << endl;derived d;d.hello();d.hello2();}{cout << "Instance is Derived - Reference is Base" << endl;base *f = new derived ;f->hello();f->hello2();}{cout << "Instance is Base - Reference is Base" << endl;base t;t.hello();t.hello2();}{cout << "Instance is Derived - reinterpret cast to base - Reference is Derived" << endl;derived *g = new derived ;base *j = reinterpret_cast<base*>(g);j->hello();j->hello2();}getchar();return 0; } And the output:
calling function defined in both base and der that is NOT virtual, then calling a function that is virtual Instance is Derived - Reference is Derived Derived func non-virtual Derived func virtual Instance is Derived - Reference is Base Base func non-virtual Derived func virtual Instance is Base - Reference is Base Base func non-virtual Base func virtual Instance is Derived - reinterpret cast to base - Reference is Derived Base func non-virtual Derived func virtual

And C#

using System;namespace ConsoleApplication2 {public class based{public void hello(){Console.WriteLine("hello on base instance - non virtual on base");Console.WriteLine("func is - non virtual on deriv");}public virtual void hello2(){Console.WriteLine("hello2 on base instance - virtual on base");Console.WriteLine("func is - virtual on deriv");}public void hello3(){Console.WriteLine("hello3 on base instance - non virtual on base");Console.WriteLine("func is new and virtual on deriv");}public virtual void hello4(){Console.WriteLine("hello4 on base instance - virtual on base");Console.WriteLine("func is new and virtual on deriv");}public virtual void hello5(){Console.WriteLine("hello5 on base instance - virtual on base");Console.WriteLine("func is override on deriv");}public void hello6(){Console.WriteLine("hello6 on base instance - NOT virtual on base");Console.WriteLine("func is override on deriv");}}public class derived : based {public void hello(){Console.WriteLine("hello on deriv - non virtual on deriv");Console.WriteLine("func is non virtual on base");}public virtual void hello2(){Console.WriteLine("hello2 on deriv - virtual on deriv");Console.WriteLine("func is virtual on base");}public new virtual void hello3(){Console.WriteLine("hello3 on deriv - new and virtual on deriv");Console.WriteLine("func is non virtual on base");}public new virtual void hello4(){Console.WriteLine("hello4 on deriv - new and virtual on deriv");Console.WriteLine("func is virtual on base");}public override void hello5(){Console.WriteLine("hello5 on deriv - override on deriv");Console.WriteLine("func is virtual on base");}}class Program{static void Main(string[] args){Console.WriteLine("base ref with base inst");based b = new based();b.hello();b.hello2();b.hello3();b.hello4();b.hello5();Console.WriteLine();Console.WriteLine("deriv ref with deriv inst");derived d = new derived();d.hello();d.hello2();d.hello3();d.hello4();d.hello5();Console.WriteLine();Console.WriteLine("base ref with deriv inst");based o = new derived();o.hello();o.hello2();o.hello3();o.hello4();o.hello5();Console.WriteLine();Console.WriteLine("deriv ref with deriv inst cast back to base ref");derived s = new derived();based ds = s;ds.hello();ds.hello2();ds.hello3();ds.hello4();ds.hello5();Console.WriteLine("The end--");Console.ReadLine();}} }
And the output:

base ref with base inst hello on base instance - non virtual on base func is - non virtual on deriv hello2 on base instance - virtual on base func is - virtual on deriv hello3 on base instance - non virtual on base func is new and virtual on deriv hello4 on base instance - virtual on base func is new and virtual on deriv hello5 on base instance - virtual on base func is override on derivderiv ref with deriv inst hello on deriv - non virtual on deriv func is non virtual on base hello2 on deriv - virtual on deriv func is virtual on base hello3 on deriv - new and virtual on deriv func is non virtual on base hello4 on deriv - new and virtual on deriv func is virtual on base hello5 on deriv - override on deriv func is virtual on basebase ref with deriv inst hello on base instance - non virtual on base func is - non virtual on deriv hello2 on base instance - virtual on base func is - virtual on deriv hello3 on base instance - non virtual on base func is new and virtual on deriv hello4 on base instance - virtual on base func is new and virtual on deriv hello5 on deriv - override on deriv func is virtual on basederiv ref with deriv inst cast back to base ref hello on base instance - non virtual on base func is - non virtual on deriv hello2 on base instance - virtual on base func is - virtual on deriv hello3 on base instance - non virtual on base func is new and virtual on deriv hello4 on base instance - virtual on base func is new and virtual on deriv hello5 on deriv - override on deriv func is virtual on base The end--


And lastly Java

package com.roboticsfordreamers;class Base implements {public void Hello(){System.out.println("Hello this the base");} }class Derived extends Base {public void Hello(){System.out.println("Hello this the derived");} }public class Main {public static void main(String[] args) {Base b = new Base();Derived d = new Derived();Base b2 = new Derived();b.Hello();d.Hello();b2.Hello();} } And the output:
Hello this the base Hello this the derived Hello this the derivedProcess finished with exit code 0

我希望你能找到對你有用知識。


原文:https://www.codeproject.com/Tips/1164135/Overriding-Virtual-Functions-a-Comparison-Between

PS:這篇有點難,部分地方翻譯不到位

總結(jié)

以上是生活随笔為你收集整理的让我们来比较C#,C++和Java之间重写虚函数的区别的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 性av网 | h视频在线免费观看 | 色666| 精品二区在线观看 | 91麻豆精品国产91久久久更新时间 | 精品国产综合区久久久久久 | 午夜福利理论片在线观看 | 久久精品国产免费 | 国精产品一品二品国精品69xx | 国产精品suv一区二区88 | 久久不射网 | 一品毛片 | 日韩av地址| 涩涩涩av | 国产精品视频999 | 国产刺激对白 | 特黄特色大片免费 | 毛片网站免费观看 | 国产精品美女www | 国产精品高潮呻吟 | 亚洲一区二区自偷自拍 | 婷婷国产精品 | 美女被猛网站 | 综合久久一区二区 | 日韩在线视频免费看 | 久热久色| √天堂8资源中文在线 | 狠狠躁18三区二区一区 | 特级西西人体444www高清 | 91视频导航 | 99精品在线免费观看 | 蜜桃久久久久久久 | 三级黄视频 | 欧美精品色婷婷五月综合 | 国产99久久久国产精品 | av中文一区 | 在线www色| 福利在线小视频 | 日操操| 久久国产精品免费视频 | 午夜男人的天堂 | 亚洲综合另类 | 久久久人妻无码一区二区 | 91精品婷婷国产综合久久蝌蚪 | 无限资源日本好片 | 亚洲综合p | 欧美xxxx精品 | 狠狠一区二区 | 91免费视 | 火影忍者羞羞漫画 | 黑人巨大精品欧美一区免费视频 | 国产欧美日韩中文字幕 | 少妇极品熟妇人妻无码 | 中文字幕第31页 | 中文字幕高清在线免费播放 | 天天射日日射 | 成人三级黄色 | 精品视频久久久久久久 | 午夜日韩在线观看 | 日韩成人一区二区 | 亚洲美女av网站 | 亚洲天堂久久 | www.日韩| 国产叼嘿视频在线观看 | 国产成人精品亚洲 | 99视频精品 | 久久久国产一区 | 在线观看黄色片网站 | 看毛片网| 爽妇网国产精品 | 婚后打屁股高h1v1调教 | 久草中文在线观看 | 黄视频免费观看 | 中文字幕一区二区三区免费视频 | 欧美 日韩 综合 | 奇米影视在线播放 | 精品成人av一区二区三区 | 交hdsexvideos娇小| 龚玥菲三级露全乳视频 | 67194国产 | 日韩a级黄色片 | 国产美女视频免费观看下载软件 | 欧美91| 人妻 日韩 欧美 综合 制服 | 成人午夜免费观看 | 自拍偷拍20p | 国产主播自拍av | 国产日产久久高清欧美一区 | 久久久精品国产免费爽爽爽 | 超碰91在线| 久久九九国产精品 | 特级毛片网站 | 干美女av | 久久久久久伦理 | 日本成人久久 | 色综合狠狠爱 | 在线观看你懂得 | 美女的胸给男人玩视频 | 亚洲蜜桃在线 |