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

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

在可管理C++中封裝值類型

2019-11-17 05:29:22
字體:
供稿:網(wǎng)友

  有些時候,一些很簡單的事情實現(xiàn)起來并不輕易。例如,我們想讓一個變量值顯示在屏幕上。也許你知道在C++中怎么做,但在VC++6中,要用下面的方法實現(xiàn):

int x = 3;cout << "x is " << x << endl;

就這么簡單。不論你學(xué)的“C++入門課”怎樣,我打賭你能發(fā)現(xiàn)的與這兩行代碼相似的東西不足你在課程中學(xué)到的10%,對嗎?

輸出到屏幕


現(xiàn)在,假如要在VC++.NET中創(chuàng)建可治理的C++程序該怎么做?下面是我創(chuàng)建的main():

int _tmain(void){ // TODO: Please replace the sample code below // with your own. Console::WriteLine(S"Hello World"); return 0;}

現(xiàn)在你可以把應(yīng)用Cout的代碼拷貝到main()中,在加入了include聲明后,就可以執(zhí)行:

#include <iostream.h>// ... Console::WriteLine(S"Hello World"); int x = 3; cout << "x is " << x << endl;

這時,你會看到一個警告:

warning C4995: '_OLD_IOSTREAMS_ARE_DE

解決的方法:借用STL中的IO流的代碼,并且導(dǎo)入std 名稱空間:

#include <iostream>using namespace std;

現(xiàn)在編譯并運(yùn)行這段代碼。但是讓我不解的是,在程序中發(fā)現(xiàn)作為cout應(yīng)用的Console::WriteLine()。另外,Console::WriteLine很整潔。就像printf,它在字符串中使用占位符顯示變量值應(yīng)該放到哪。下面是一個c#控制程序中的代碼:

int x = 3;Console.WriteLine("x is {0}",x);

{0}是一個占位符,第二個參數(shù)的值截止到占位符出現(xiàn)的位置。因此我想像在c#中一樣,在可治理的c++程序中一直使用Console::WriteLine。但是假如你把代碼直接拷到c++程序中,并將.改為::,程序不能通過編譯。錯誤顯示為:

error C2665: 'System::Console::WriteLine' : none of the 19 overloads can convert parameter 2 from type 'int' boXPin.cpp(7): could be 'void System::Console::WriteLine(System::String __gc *,System::Object __gc *)' boxpin.cpp(7): or 'void System::Console::WriteLine(System::String __gc *,System::Object __gc * __gc[])' while trying to match the argument list '(char [9], int)'

現(xiàn)在,我固執(zhí)地希望c++能做其他.net語言能做的所有事情,甚至更多。為什么這么簡單的辦法行不通?沒別的辦法,看看錯誤提示吧。我給第二個參數(shù)賦一個整數(shù)值,它就像一個指針。事實上,是一類指向System::Object的指針(當(dāng)然,還有由其衍生出的類),一類指向__gc object的指針。而這個整數(shù)值兩種都不是。你可以試著傳遞&x值,而非x,那樣至少是一個指針,但還是無濟(jì)于事。

WriteLine()需要的是一個指向?qū)ο蟮闹羔槨D悴荒苤苯訉⒄麛?shù)值傳遞給WriteLine(),因為它是(處于整體性的考慮)用來處理指向垃圾收集對象的指針,而不是其他的。為什么?基本類庫中的所有內(nèi)容都是針對對象設(shè)計的,因為他們都可有成員函數(shù)——并不是所有的.net語言都支持模式化或是過載模式化運(yùn)算符的思想。比如,由System::Object繼續(xù)下來的所有對象都有一個ToString() 方法。你不想為一個非對象的整數(shù)寫一個類,然后又寫一個ToString()來處理它,在每次將它傳遞給像WriteLine()基本類庫中的方法的時候,還要把它放入(或取出)。這時,你怎么把整數(shù)傳遞給WriteLine()?

_box要害字


可治理的c++也被稱為c++可治理的擴(kuò)展。擴(kuò)展是指額外要害字,都是以雙下劃線開頭,并被增加到語言中。和其他所有以雙下劃線開始的要害字一樣,他們的編譯器是特定的——不要在vc++6和其他產(chǎn)商的編譯器中試用。在編譯WriteLine() 時,你只會在錯誤信息中看到_gc。它代表著垃圾收集并且指向一個依靠堆棧類型,并由運(yùn)行時間控制的對象。_box要害字可以解決我在上面提到的,如何將整數(shù)傳給基本類庫方法,它得到的是System::Object _gc而不是一個整數(shù)。下面是它的使用方法:


Console::WriteLine("x is {0}",__box(x));
封裝一個值的類別就是把值放到一個臨時對象(這個對象是System::Object繼續(xù)類的實例,存于垃圾收集堆)中,然后再把臨時對象的地址傳遞給方法調(diào)用。原有變量中所有的東西都被拷入臨時對象中,這個對象提供WriteLine()需要的所有功能。__box要害字意味著值類型和可治理類型都適合于基本類庫提供的所有服務(wù)。

封裝的替代辦法


裝箱答應(yīng)你在期待指向可管指針的基本類庫的方法中使用值類型和可治理類型。這自然產(chǎn)生了一個問題:在值類型和可治理類型中究竟有什么區(qū)別?可治理類型存于垃圾收集堆中,并且被運(yùn)行時間所治理。下面是一個例子:

__gc class Foo{ // internals omitted};// ...Foo* f = new Foo();

FOO類是可治理類型。你不能在堆棧上創(chuàng)建Foo f2;這樣的實例:

假如你已經(jīng)有一個類(也許是從以前的.net程序中獲得),它一定不是一個可治理類型。它沒有_gc要害字。當(dāng)然,你可以加上要害字(假設(shè)類符合成為一個可治理類型的所有條件),但接下來你要找到所有創(chuàng)建類實例的地址,還有保證他們是在堆上創(chuàng)建的實例,比如:

OldClass* poc = new OldClass(); //maybe some parameters //to the constrUCtor

你要記住,在代碼中調(diào)用類方法的每一處,都要把.改為->。保持原來的類型,這樣你可以按照你的意愿在堆棧或未治理的堆上分配實例:

class notmanaged{private: int val;public: notmanaged(int v) : val(v) {};};// ... notmanaged nm(4); notmanaged *p = new notmanaged(5);

這并不難:這就是還沒發(fā)布加入可治理擴(kuò)

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 莆田市| 古交市| 油尖旺区| 龙川县| 舒城县| 喀喇沁旗| 平南县| 安吉县| 赫章县| 徐闻县| 玉树县| 闽清县| 谷城县| 梓潼县| 夏邑县| 肃宁县| 苗栗县| 凯里市| 柏乡县| 华亭县| 南宁市| 南通市| 澄迈县| 徐闻县| 合川市| 盐津县| 江永县| 阳信县| 任丘市| 巫山县| 文安县| 台东市| 昌乐县| 泸水县| 红原县| 盱眙县| 吉安市| 玉山县| 揭东县| 赫章县| 尚志市|