<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    302班

    java突擊隊
    posts - 151, comments - 74, trackbacks - 0, articles - 14
      BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理

    C++轉向C#要注意的幾個變化

    Posted on 2007-06-15 19:49 停留的風 閱讀(145) 評論(0)  編輯  收藏
      每隔10年左右,編程人員就需要花費大量的時間和精力去學習新的編程技術。在80年代是Unix和C,90年代是Windows和C++,現在又輪到了微軟的。NETFramework和C #.盡管需要學習新的技術,但由此帶來的好處卻遠高于付出的勞動。幸運的是,使用C#和。NET進行的大多數工程的分析和設計與在C++和Windows中沒有本質的變化。在本篇文章中,我將介紹如何實現由C++到C#的飛躍。

        已經有許多文章介紹過C#對C++的改進,在這里我就不再重復這些問題了。在這里,我將重點討論由C++轉向C#時最大的變化:由不可管理的環境向可管理的環境的變化。此外,我還會提出一些C#編程人員容易犯的錯誤供大家參考,此外,還將說明一些C#語言的能夠影響編程的新功能。

        轉向可管理的環境

        C++的設計目標是低級的、與平臺無關的面向對象編程語言,C#則是一種高級的面向組件的編程語言。向可管理環境的轉變意味著你編程方式思考的重大轉變,C#不再處理細微的控制,而是讓架構幫助你處理這些重要的問題。例如,在C++中,我們就可以使用new在棧中、堆中、甚至是內存中的某一特定位置創建一個對象。

        在。NET的可管理環境中,我們再不用進行那樣細微的控制了。在選擇了要創建的類型后,它的位置就是固定的了。簡單類型(ints、double和long)的對象總是被創建在棧中(除非它們是被包含在其他的對象中),類總是被創建在堆中。我們無法控制對象是創建在堆中哪個位置的,也沒有辦法得到這個地址,不能將對象放置在內存中的某一特定位置。(當然也有突破這些限制的方法,但那是很另類的方法。)我們再也不能控制對象的生存周期,C#沒有destructor.碎片收集程序會將對象所占用的內存進行回收,但這是非顯性地進行的。

        正是C#的這種結構反映了其基礎架構,其中沒有多重繼承和模板,因為在一個可管理的碎片收集環境中,多重繼承是很難高效地實現的。

        C#中的簡單類型僅僅是對通用語言運行庫(CLR)中類型的簡單映射,例如,C#中的int是對System.Int32的映射。C#中的數據類型不是由語言本身決定的,而是由CLR決定的。事實上,如果仍然想在C#中使用在VisualBasic中創建的對象,就必須使自己的編程習慣更符合CLR的規定。

        另一方面,可管理的環境和CLR也給我們帶來了好處。除了碎片收集和所有。NET語言中統一的數據類型外,它還提供給我們一個功能強大的面向組件的編程語言,無須對后期綁定提供特別的支持,類型發現和后期綁定都是被內置在語言中的。屬性是C#語言中的第一類的成員,事件和代理也是。

        可管理環境最主要的優點是。NETFramework.盡管在所有的。NET語文中都可以使用這種框架,但C#可以更好地使用。NET框架中豐富的類、接口和對象。

        Traps

        C#看起來與C++非常相似,這使得我們在由C++轉向C#時比較輕松,但其中也有一些容易出錯的地方。在C++中編寫得非常漂亮的代碼,在C#中會不能通過編譯,甚至會出現意想不到的結果。C#與C++之間在語法上的變化并不大,編譯器能夠發現這二者之間大部分的差異,我在這里就不再多費筆墨了,在這里我介紹幾個容易出問題的比較重要的變化:

        引用類型和值類型

        在C#中,值類型和引用類型數據是有區別的。簡單類型(int、long、double等)和結構屬于值類型數據,類和對象屬于引用類型數據。除非是包含在引用類型的變量中,與在C++中一樣,值類型變量的值存儲在棧中。引用類型的變量也存儲在棧中,但它的值是一個存儲在堆中的對象的地址,這一點也與C++類似。值類型變量是將自己的值傳遞給方法,而引用類型變量則將自己的指針傳遞給方法。

      結構

        C#中的結構與C++中有非常明顯的區別。在C++中,結構更象是類,除了缺省的繼承外,其缺省的訪問權限是public而不是private.在C#中,結構與類截然不同,它是用來封裝輕型對象的,是值類型的數據類型,在傳遞時傳送的是變量的值,而不是其地址。此外,它們也有一些不適用于類的限制,例如,它是不能繼承的,也沒有除System.ValueType之外的基本類。結構還不能定義一個缺省的constructor.

        另一方面,由于結構比類的效率要高,因此它非常適合于創建輕型對象。因此,如果它的缺點對你的軟件沒有影響,使用結構比使用類效率要高得多,尤其是對于小對象而言。

      所有的一切都是對象

      在C#中,所有的東西都是由繼承Object得到的,包括創建的類和int、structs等值類型的變量。Object類提供了一些有用的方法,例如ToString,使用ToString的一個例子是與System.Console.WriteLine一起使用,它可以接受一個字符串和許多對象。與使用printf語句不同,要使用WriteLine,需要提供代換變量。假設myEmployee是用戶定義的Employee類的一個實例,myCounter是用戶定義的Counter類的一個實例:


      Console.WriteLine("Theemployee:{0},thecountervalue:{1}",
      myEmployee,myCounter);

     

      其中的WriteLine會調用每個對象的Object.ToString方法,替換作為參數返回的變量。如果Employee類不覆蓋ToString,就會調用缺省的實現(由System.Object繼承得到的),它將把類的名字作為一個字符串返回。Counter會覆蓋ToString,返回一個整型的變量,因此,上面代碼的輸出為:


      Theemployee:Employee,thecountervalue:12

      如果向WriteLine傳遞一個整型變量會發生什么情況呢?由于不能對整型變量調用ToString,編譯器將自動將整型變量封裝在一個對象的實例中。當WriteLine調用ToString時,對象就會返回表示整型變量值的字符串。下面的代碼就說明了這個問題:

      類的使用


      usingSystem;
      //不覆蓋ToString的類
      publicclassEmployee
      {
      }
      //覆蓋了ToString的類
      publicclassCounter
      {
      privateinttheVal;
      publicCounter(inttheVal)
      {
      this.theVal=theVal;
      }
      publicoverridestringToString()
      {
      Console.WriteLine("CallingCounter.ToString()");
      returntheVal.ToString();
      }
      }


      publicclassTester
      {
      publicstaticvoidMain()
      {
      //創建類的實例
      Testert=new
    Tester();
      //調用非靜態成員
      //(mustbethroughaninstance)
      t.Run();
      }
      //演示調用ToString的非靜態方法
      publicvoidRun()
      {
      EmployeemyEmployee=newEmployee();
      CountermyCounter=newCounter(12);
      Console.WriteLine("Theemployee:{0},thecountervalue:{1}",
      myEmployee,myCounter);
      intmyInt=5;
      Console.WriteLine("Herearetwointegers:{0}and{1}",17,myInt);
      }
      }

     

      引用型參數和輸出型參數

      與C++中相同,C#中的方法也只能有一個返回值。在C++中,我們通過將指針或索引作為參數而克服了這個限制,被調用的方法改變其中的參數,調用方法就可以得到新的值了。

      向方法中傳遞一個索引作為參數時,只能嚴格地按傳遞索引或指針所能夠提供的方式訪問原來的對象。對于值類型變量而言,就不能采用這種方法了。如果要通過引用型參數傳遞值型變量,就需要在其前面加上ref關健字。如下所示:


      publicvoidGetStats(refintage,refintID,refintyearsServed)

      需要注意的是,既需要在方法的定義中使用ref關健字,也需要在對方法的實際調用中使用ref關健字。


      Fred.GetStats(refage,refID,refyearsServed);

      現在,我們可以在調用方法中定義age、ID和yearsServed變量,并將它們傳遞給GetStats,得到改變后的值。

      C#要求明確的賦值,也就是說,在調用GetStats方法之前,必須對age、ID和yearsServed這三個局部變量進行初始化,這一工作似乎有點多余,因為我們僅僅使用它們從GetStats中得到新的變量的值。為了解決這一問題,C#提供了out關健字,表示我們可以向方法中傳遞沒有被初始化的變量,這些變量將通過引用變量的方式進行傳遞:


      publicvoidGetStats(outintage,outintID,outintyearsServed)

      當然了,調用方法也必須作出相應的變化:


      Fred.GetStats(outage,outID,outyearsServed);


    只有注冊用戶登錄后才能發表評論。


    網站導航:
     
    主站蜘蛛池模板: 免费无码一区二区三区蜜桃| 国产av无码专区亚洲av毛片搜| 在线看片免费人成视频久网下载| 狼友av永久网站免费观看 | 国内精品99亚洲免费高清| 久久久久久久久无码精品亚洲日韩| 成年人视频在线观看免费| 亚洲首页国产精品丝袜| 成人免费a级毛片| 在线a亚洲老鸭窝天堂av高清| 全免费a级毛片免费看不卡| 亚洲成熟丰满熟妇高潮XXXXX| 国产yw855.c免费视频| 九九免费精品视频在这里| 人人狠狠综合久久亚洲婷婷| 久久精品免费观看国产| 亚洲同性男gay网站在线观看| 岛国大片免费在线观看| 色多多免费视频观看区一区| 国产亚洲AV夜间福利香蕉149| 午夜精品免费在线观看| 亚洲av乱码一区二区三区| 日本特黄特黄刺激大片免费| 好猛好深好爽好硬免费视频| 久久精品亚洲中文字幕无码麻豆| 99热在线精品免费全部my| 久久精品国产亚洲AV天海翼| 中文字幕精品亚洲无线码二区 | 亚洲国产另类久久久精品黑人| 最近免费中文字幕高清大全| 亚洲精品国产首次亮相| 久久久亚洲精品蜜桃臀| 亚洲毛片在线免费观看| 国产亚洲视频在线观看| 亚洲AV成人片色在线观看高潮| 免费中文熟妇在线影片| 91av免费在线视频| 亚洲成aⅴ人片在线观| 亚洲国产成人五月综合网| 5g影院5g天天爽永久免费影院| 久久精品熟女亚洲av麻豆|