程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++ VS C#(13):隱藏基類方法,部分類定義

C++ VS C#(13):隱藏基類方法,部分類定義

編輯:C++入門知識

//=====================================================================
//TITLE:
//    C++ VS C#(12):函數的重載,類成員的static修飾,屬性
//AUTHOR:
//    norains
//DATE:
//    Monday  04-April-2011
//Environment:
//    Visual Studio 2010
//    Visual Studio 2005
//=====================================================================

1. 函數的重載

    在C++中,對象函數的重載只有一個原則,就是派生類和基類的函數名必須相同,除此以外,並無更多的約束,如:

   class CBase
   {
   public:
    virtual int Add(){};
   };
  
   class CDerived:
    public CBase
   {
   public:
    virtual int Add(){};
   };
  
    函數前的virtual只是告訴編譯器,當用基類指針指向派生類對象時,調用的應該是派生類的Add函數;而如果沒有virtual,那麼在相同的情形之下,調用的則是基類本身的Add。但不管有無virtual,編譯器都不會作出任何提示或警告。
  
    相對於C++而言,C#在這方面就智能一點。如果基類沒有采用virtual關鍵字,並且派生類也沒有采用override,那麼編譯器會有類似的警告:
   warning CS0114: Function.CDerived.Add() hides inherited member Function.CBase.Add(). To make the current member override that implementation, add the override keyword. Otherwise add the new keyword.
  
    不要小看這個不起眼的警告,也許在不少場合能幫上大忙。比如基類是由同事寫的,並且其代碼需要調用到派生類的某個重載函數,而你也確實重載了;但在隨後的工作中,同事覺得這函數名不好看或什麼雜七雜八的理由,更改了函數名,那麼災難就發生了,你重載的函數永遠無法調用!如果有了這麼一個警告,說不定類似的情形還能夠避免。
  
    C#對於函數的修飾符,比C++多了三個,其功能列表如下:

修飾符
 說明
 
virtual
 方法可以重寫
 
abstract
 方法必須在非抽象類的派生類中重寫
 
override
 重寫了基類的一個方法
 
extern
 方法定義在其它地方
 


2. 類成員的static修飾

    如果將static在class中使用,那麼C++和C#有個非常明顯的區別:在C#裡,static修飾過的函數或變量,不能夠通過對象來訪問,而必須使用類來訪問;而在C++中,則無此限制。
  
    我們來看看這個C++代碼,注意代碼中的注釋:
   class CBase
   {
    public static int iVal;
   };
  
   int CBase::iVal = 0; //初始化static變量
  
   int _tmain(int argc, _TCHAR* argv[])
   {
    int iVal = 0;
   iVal = CBase.iVal;//通過類來訪問
  
    CBase myObj;
    iVal = myObj.iVal;//通過對象來訪問
  
    return 0;
   }
  
    但對於C#來說,情形確實大為不同,如下代碼所示:
   class CBase
   {
       public static int iVal = 0;
   };
  
   static void Main(string[] args)
   {
       int iVal = 0;
  
       CBase myObj = new CBase();
       iVal = myObj.iVal; //該代碼出錯,因為static成員不能通過對象來訪問
  
       iVal = CBase.iVal; //只能通過類來訪問static成員
   }
  
    個人更喜歡C++的方式,因為類本來就是一個抽象的層次,對象是具體化的階段,類可以訪問的話,那麼對象也應該可以訪問,畢竟static是所有對象所共有的,通過對象不能訪問static成員,無論如何也覺得情理不通。
  
    關於static還有一個區別,細心的朋友可能發現了,C++中的static變量聲明是無法直接初始化的,而必須在.cpp中進行;至於C#,本來就沒有頭文件的存在,所以也無所謂外部定義,直接賦值即可。這點上,C#做的更好些。

  
  
  
3. 屬性

    屬性這玩意就沒啥差異可說,當然並不是C++和C#是一樣的,而是因為C++根本就沒這東西,是C#所獨有的。因為C++程序員可能對此不明白,所以特意提一下。
  
    所謂的屬性,就是采用get和set的代碼塊,是作用於成員變量的,並且只有當操作符為"="時有作用。估計這樣說,誰都會頭疼,我們還是來看看實際的代碼,如下所示:
   class CBase
   {
       private int iInternal = 0;
       public int iVal
       {
           get
           {
       //返回iInternal變量的數值
               return iInternal;
           }
  
           set
           {
       //設置iInternal的數值
               iInternal = value;
           }
       }
   };
  
  
   CBase myObj = new CBase();
   int iVal = myObj.iVal; //調用iVal 變量的get方法
   myObj.iVal = 5; //調用iVal 變量的set方法
   


    以一種不恰當的比喻說明,get和set就像是針對某個變量重載其"="操作符。C#屬性的方式,打破了C++的一個信條:成員變量都應該聲明為private,對其的存儲盡可能使用函數的方式。當然,C#的所謂打破,其實也是形式上的打破,本質上其實也是遵循該信仰:如果直接通過對象來訪問成員變量,當其賦值或獲取不符合要求,就用get和set改變其行為。對於C++的程序員來說,可能唯一礙眼的僅僅是myObj.iVal這樣的形式而已。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved