国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 開發(fā) > 綜合 > 正文

C++的類與C#的類[zt]

2024-07-21 02:22:14
字體:
供稿:網(wǎng)友
微軟公司給c#(讀為c-sharp)賦予c++某些面向?qū)ο蟮谋举|(zhì),比如模板,但改變了類的創(chuàng)建方法。本文,我將對比c++和c#的類,并著重說明微軟在c#中類創(chuàng)建和使用方面的改變。

一、簡介
面向?qū)ο?oo)編程在應(yīng)用設(shè)計(jì)中已經(jīng)發(fā)展二十來年了。程序不再是一系列函數(shù)的堆徹(象一些范例那樣的程序),而是對象的集合,每個(gè)對象都有其獨(dú)特的屬性和方法來與其它對象打交道。

"c"語言系列是面向?qū)ο笤O(shè)計(jì)發(fā)展的最好例子。c++為開發(fā)者提供了優(yōu)秀的面向?qū)ο缶幊坦ぞ撸绦騿T可以顯式地創(chuàng)建構(gòu)造函數(shù),拷貝構(gòu)造函數(shù),重載操作符,使用模板等等。

象c++這樣復(fù)雜語言的主要問題是程序員要花上好幾個(gè)月來掌握面向?qū)ο笤O(shè)計(jì)本質(zhì)。新程序員必須學(xué)會掌握模板,函數(shù)重載,當(dāng)然還要會創(chuàng)建和使用功能良好的類。

微軟公司給c#(讀為c-sharp)賦予c++某些面向?qū)ο蟮谋举|(zhì),比如模板,但改變了類的創(chuàng)建方法。本文,我將對比c++和c#的類,并著重說明微軟在c#中類創(chuàng)建和使用方面的改變。

本文對象是熟練的c++程序員,通過一些細(xì)節(jié)來解釋c#面向?qū)ο蟮谋举|(zhì)。

二、c#的類有了哪些改變?
如你所知,c#是部分基于c++,部分基于java語法的語言。c#中還有一些細(xì)節(jié)上的改變,使得它可以用于現(xiàn)代設(shè)計(jì)。

當(dāng)你開始用c#建類時(shí)就會立即看到這點(diǎn)。讓我們通過一個(gè)簡單的例子開始了解在c++和c#中是如何建類并進(jìn)行實(shí)例化的。

c++版本:
#include <iostream>

class myclass
{
 public: void dosomething()
 {
  std::cout << "this is some text";
 }
};

void main()
{
 myclass mc;
 mc.dosomething();
}

c# 版本:
using system;

class myclass
{
    public void dosomething()
    {
        console.writeline("this is some text");
    }
}

class entrypoint
{
    public static void main()
    {
        myclass mc = new myclass();
        mc.dosomething();
    }
}

上面的代碼中有幾個(gè)不同之處。
首先,c++用#include包含語句來指明包含文件iostream.h的物理路徑。c#則告訴編譯器程序?qū)⒃趕ystem命名空間下操作,所有的命名空間和類都屬于system命名空間。c#通過命名空間的名字來決定程序的作用范圍(本例中只有system一個(gè)命名空間),而不用指明物理路徑的包含文件方法。
其次,c#的主程序用main(注意m是大寫)。
第三,c++的類聲明結(jié)束后要在最后的大括號后面用分號結(jié)尾。c#則可用可不用,往往都是省略。
第四,你能看到在c#中必須顯式地聲明方法和成員的作用域。若不加聲明,缺省為私有(只有類成員可以訪問),這點(diǎn)與c++一樣。c#中有5種作用域:
 公有(public):其他類成員也可以訪問
 私有(private):只有類成員才能訪問
 保護(hù)(protected):類成員和繼承類成員可以訪問
 內(nèi)部(internal):只有匯編里的成員才能訪問(c#的匯編是代碼和資源數(shù)據(jù)的結(jié)合,以asmx作文件后綴)
 內(nèi)部保護(hù)(protected internal):類成員和繼承類成員可以訪問
最后,與java一樣,c#的方法也可以聲明為靜態(tài)(static)的。靜態(tài)變量的使用在c#和c++是一樣的。在c#里,可以這樣創(chuàng)建并調(diào)用類的靜態(tài)方法:
using system;

class myclass
{
 public static void dosomething()
 {
  console.writeline("this is some text");
 }
};

class entrypoint
{
 public static void main()
 {
  myclass.dosomething();
 }
}

注意,這里直接使用類聲明而沒有創(chuàng)建類的實(shí)例。這是為c#語言增加的非常便利的使用方法,可以節(jié)省我們的時(shí)間和內(nèi)存。就是說,不要?jiǎng)?chuàng)建類實(shí)例,可以直接調(diào)用類的方法。

三、用類修飾語限制對類的訪問
以前只能對類成員和類方法設(shè)定限制,但不能對類實(shí)體作限制。c#可以通過聲明類修飾語來對類的實(shí)例實(shí)行限制,如上節(jié)提到的作用域。

c++不能對整個(gè)類作限制。看一下c++的類聲明:
class car
{
 public:
  car();
  car(car &c);
  virtual ~car();

 private:
  int numcars;
  car* previous;
  car* next;
};

這里有二種訪問類型:公有(public)和私有(private)。繼承或?qū)㈩恈ar實(shí)例化后,程序只能繼承這些代碼,不能作其它變動(dòng),如果要作其它變動(dòng)就不能將其作為基類。

c#對此了改變。可以附加訪問修飾語來限制類成員和方法以及類實(shí)例的訪問權(quán)。c#設(shè)定8個(gè)訪問權(quán)限:
 公有(public):可以被所有其它的類訪問。沒有其它限制修飾語,它的公有性質(zhì)就一直是缺省的。
 私有(private):只有類成員才能訪問。
 保護(hù)(protected):類成員和繼承類成員可以訪問。
 內(nèi)部(internal):只有匯編里的成員才能訪問(c#的匯編是代碼和資源數(shù)據(jù)的結(jié)合,以asmx作文件后綴)。
 內(nèi)部保護(hù)(protected internal):類成員和繼承類成員可以訪問。
 密封(sealed):所有繼承類都不能訪問。無論直接或間接地將它作為基類,c#編譯器都會跳錯(cuò)。
 抽象(abstract):與c++的虛(virtual)類或虛方法相似,抽象類不能直接實(shí)例化,抽象函數(shù)含有函數(shù)名。但在作為基類或繼承類時(shí)可以使用。
 新建(new):用new創(chuàng)建嵌套類,可以隱藏繼承方式,告訴編譯器創(chuàng)建一個(gè)類的新版本。
 
舉例來說,如果要?jiǎng)?chuàng)建一個(gè)類,并且這個(gè)類不能被作為基類或繼承,那么就要?jiǎng)?chuàng)建一個(gè)密封類:
sealed class car
{
 public void paintcar()
 {
  // code to paint car goes here
 }
}

這時(shí)如果要?jiǎng)?chuàng)建一個(gè)繼承類redcar:
internal class redcar : car
{
 // won't work.
}

c#編譯器就會跳錯(cuò):
error cs0509: 'redcar' : cannot inherit from sealed class 'car'  (不能從密封類'car'繼承)。

四、c++和c#中的虛函數(shù)
c++和c#都支持虛函數(shù)。在下面的c++例子里,有二個(gè)類,分別稱為base(基類)和derived(繼承類):

#include <iostream>
using namespace std;

class base
{
 public:
  void dowork()
  {
   cout << "base class working";
  }
 protected:
  virtual void dowork1() = 0;
};

class derived : public base
{
 public:
  void dowork2()
  {
   cout << "derived class working";
  }
  void dowork1()
  {
   cout << "dervied pure virtual function working";
  }
};

void main()
{
 derived d;
 d.dowork1();
}

基類里有二個(gè)函數(shù),一個(gè)是dowork,另一個(gè)是純虛函數(shù)dowork1。dowork1只能被基類的繼承類使用。在繼承類(公有地繼承于基類)里有一個(gè)新函數(shù)dowork2,和繼承于基類純虛函數(shù)的超越函數(shù)dowork1。
在c#里實(shí)現(xiàn)同樣的功能要更容易些。看下面的c#代碼:

using system;

abstract class base
{
 public void dowork()
 {
  console.writeline("base class working");
 }

 public abstract void dowork1();
}

class derived : base
{
 public void dowork2()
 {
  console.writeline("derived class working");
 }

 public override void dowork1()
 {
  console.writeline("dervied pure virtual function working");
 }
};

class entrypoint
{
 public static void main()
 {
  derived d = new derived();
  d.dowork1();
 }
}

c#將基類定義為抽象類,將dowork1定義為抽象方法。這樣就可以獲得與上述c++純虛函數(shù)同樣的功能。base類只能作為基類或被含有dowork1超越函數(shù)的繼承類使用。

繼承類在超越抽象函數(shù)dowork1時(shí),在函數(shù)前面加上超越前綴(override)。c#編譯器在發(fā)現(xiàn)繼承類里的override關(guān)鍵字后,就檢查基類的同名函數(shù)。只要不是直接顯式地調(diào)用基類函數(shù),編譯器總是使用繼承類中的方法。

為了讓繼承類直接操作基類成員和方法,c# 為基類命名了一個(gè)別名base。用這個(gè)別名,繼承類可以直接引用基類成員和方法。示例如下:

using system;

class first
{
 public void writeit()
 {
  console.writeline("writing from base class");
 }
}

class second : first
{
 public second()
 {
  base.writeit();
 }
}

class entrypoint
{
 public static void main()
 {
  second s = new second();
 }
}

在上述例子中,有二個(gè)類。一個(gè)是基類(first),另一個(gè)是繼承類(second)。當(dāng)創(chuàng)建second類的實(shí)例時(shí),它的構(gòu)造函數(shù)自動(dòng)調(diào)用基類的writeit方法,用控制臺指令console.writeline打印屏幕。由此引出c++和c#中的多態(tài)性。

五、c++和c#中的多態(tài)性
實(shí)體的多態(tài)性使其具有多種表現(xiàn)形式。在c++和c#中處理多態(tài)性是很相像的。看一個(gè)簡單例子:

c++ 版本:

#include <iostream>
#include <string>
using namespace std;

class person
{
 public:
  person()
  {
   classtype = "person";
  }

 friend void showtype(person& p);

 private:
  string classtype;
};

class manager : public person
{
 public:
  manager()
  {
   classtype = "manager";
  }

 friend void showtype(person& p);

 private:
  string classtype;
};

void showtype(person& p)
{
 cout << p.classtype << endl;
}

void main()
{
 person p;
 manager m;

 showtype(p);
 showtype(m);
}

c# 版本:

using system;

class person
{
 public person()
 {
  classtype = "person";
 }

 public string classtype;
}

class manager : person
{
 public manager()
 {
  classtype = "manager";
 }

 public new string classtype;
}

class entrypoint
{
 public static void showtype(ref person p)
 {
  console.writeline(p.classtype);
 }

 public static void main()
 {
  person p = new person();
  person m = new manager();

  showtype(ref p);
  showtype(ref m);
 }
}

在上面的例子里,有一個(gè)基類person,一個(gè)繼承于基類的manager類。在entrypoint類里,創(chuàng)建了一個(gè)靜態(tài)函數(shù)showtype,其表達(dá)為:
public static void showtype(ref person p)

注意參數(shù)里的ref關(guān)鍵字。ref告訴c#編譯器向showtype函數(shù)傳遞一個(gè)參數(shù)的引用(reference)。在c#中,如果不用ref關(guān)鍵字,函數(shù)的參數(shù)傳遞缺省為值(value)傳遞,將拷貝一個(gè)參數(shù)值傳遞到函數(shù)中去。
在c++中的參數(shù)引用傳遞表達(dá)為:
void showtype(person& p)
c++用"&"符號表示參數(shù)引用使得程序員新手感到困惑,尤其是那些從vb轉(zhuǎn)過來的人。

在c#的主函數(shù)(entry point)里,創(chuàng)建了二個(gè)新的person對象,p和m:
person p = new person();
person m = new manager();

值得一提是,關(guān)鍵字new在c#和c++中用法是不一樣的。在c#里,new只創(chuàng)建一個(gè)對象實(shí)例。這個(gè)對象依然創(chuàng)建在管理堆里,但不返回指向?qū)ο蟮膬?nèi)存地址的指針。在上面的c#例子中,創(chuàng)建了二個(gè)person類對象。第二個(gè)對象,m,卻是manager類的對象。它使用manager的構(gòu)造函數(shù)而不是用person的構(gòu)造函數(shù)。

將person類對象和manager類對象引用到showtype函數(shù),記住,manager是person的繼承類,但c#的多態(tài)性將其表達(dá)為一個(gè)person類:

showtype(ref p);
showtype(ref m);

當(dāng)作用到showtype函數(shù)時(shí),它只處理person對象。c#告訴它說m是person繼承類的對象,它就將m按person類處理了。所以用p和m作參數(shù)調(diào)用showtype函數(shù)后得到的輸出為:
person
person

[譯者注:這樣解釋多態(tài)性有點(diǎn)離譜。這段 c#代碼的真正含義在于詮釋靜態(tài)函數(shù)的作用,而不是什么多態(tài)性。上面一段c++代碼則可以看成多態(tài)性用法的解釋。]

六、結(jié)論
在我熟悉c#之前,我用了4年vb和2年c++。我可以負(fù)責(zé)地說,c#是我用過的語言中最具活力和靈活性并使人愉快的語言,而且它是100%面向?qū)ο蟮摹?br>
如果你是一個(gè)c++程序員,現(xiàn)在想轉(zhuǎn)向電子商務(wù)編程或干脆就是想換一種更現(xiàn)代的語言,那么就是c#了。有這么三種原因:

如果會使用c#,你就能創(chuàng)建任何應(yīng)用:windows應(yīng)用,控制臺應(yīng)用,web應(yīng)用和web服務(wù)等等。
所有的.net平臺使用的語言都編譯成為中間語言(il),并能按照系統(tǒng)環(huán)境進(jìn)行優(yōu)化。
非常非常容易將c++轉(zhuǎn)換成c#。


發(fā)表人信箱: [email protected] 
發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 且末县| 辽源市| 临沂市| 襄垣县| 湘乡市| 疏勒县| 乌什县| 启东市| 德阳市| 宁化县| 资源县| 嵩明县| 商南县| 普定县| 双柏县| 师宗县| 乐安县| 广东省| 宁都县| 秦皇岛市| 濮阳县| 滦南县| 周至县| 安西县| 五指山市| 凤翔县| 喀什市| 江油市| 历史| 广汉市| 会东县| 宜兰县| 娄烦县| 格尔木市| 通化县| 饶平县| 五常市| 邵武市| 屏南县| 老河口市| 孟连|