结合泛型与模板的STL.NET
??
???????? 開始之前,先來看一個笑話,當問一個C++程序員怎樣完成一個給定的任務時,他(她)可能會提供一打或更多的潛在解決方案列表,但又會極其詳細地標出每種方案的問題之處,讓你不知所措,難以選擇。而Visual C++ 2005,通過C++/CLI語言聯編,引入了泛型的概念,使C++程序員可進一步提高程序的開發效率。關于 .NET泛型與C++模板,盡管句法上很相似,但泛型與模板是以完全不同的方法實現的,它們之間沒有任何的內置兼容性。
??
???????? 說到泛型與模板的差別,相信每個 .NET平臺的C++程序員都會問這個問題:我該選擇哪種技術呢?那些已用C++進行了數年開發(特別是用Visual C++)的人,相信早已知道答案:兩種技術都具有卓越的特性,但任何一者都不是另一者的超集,使用何種技術只限于給定的任務,簡而言之,沒有一種技術可以適用于所有情況下的解決方案。同樣,這種進退兩難的狀況也折磨了Visual C++程序員數年:Win32或是MFC、ATL或是WTL、COM或是C風格的DLL、#import或是CComPtr。
??
?
???????? 涉及 .NET開發的C++知識
???????? 在過去,Visual C++利用某些技術手段,可使STL中的集合與其他技術協同工作,如在活動模板庫(ATL)中稱為CComEnuOnSTL的模板化類,它允許一個Visual Basic客戶端使用For Each來枚舉由C++ COM服務器提供的STL集合的內容。雖然這種層次上的集成非常之淺,但在許多受限情況下證實非常有用?;谕瑯拥闹髦?#xff0c;STL.NET為C++程序員提供了標準STL庫的一種擴展,這種擴展可允許在一個C++/CLI程序集內部使用的STL集合,作為泛型集合暴露給其他的 .NET程序集。
????????? STL.NET提供了與標準STL集合相同的接口,因此,對熟悉標準STL集合與算法的C++程序員來說,不存在學習曲線。以Visual C++ 2005來作說明,STL.NET的頭文件位于Cliext目錄中,如果要使用STL.NET集合,例如vector,必須包含<cliext/vector>而不是標準的<vector>,另外,STL.NET集合包含在cliext命名空間中,而不是標準STL集合所使用的std命名空間。
??
???????? 注:Visual C++開發小組仍在努力工作使STL.NET變得更易使用,并提高它的性能。因為STL.NET仍在不斷地進行新的改進,本文將不會探討STL.NET集合的過深之處,而會從一種更高的角度來看,為什么STL.NET將會大有作為。
??
?
???????? 橋接泛型與模板
???????? 橋接泛型與模板這兩個不同的世界,實屬一項艱巨的任務。模板只是一個C++的概念,并只存在于編譯時期;然而,泛型是一個 .NET概念,它存在于已編譯的程序集中,并對所有 .NET語言可用。STL.NET所使用的解決方案是把類集當作C++模板類來實現,同時C++模板類也是 .NET引用類型,并由其實現了ICollection泛型接口。STL與STL.NET中vector的聲明演示了這種設計:
??
//STL vector 聲明
template<class _Ty, class _Ax = allocator<_Ty> >
???????? class vector;
?
//STL.NET vector 聲明
template<typename _Value_t>
?? ref class vector : Generic::ICollection<_Value_t>
?
???????? 在這兩者的聲明當中,有一些關鍵的不同之處,除泛型接口的實現之外,STL.NET vector并不能指定一個分配算符,只是簡單地調用gcnew來分配一個新的所需元素。STL.NET集合聲明時使用了ref關鍵字,這意味著它們都是 .NET引用類型,將會被分配在 .NET托管堆中。
??
?
???????? 使用STL.NET
???????? 除去STL.NET集合聲明時的一些差異(這個差異與C++/CLI和標準C++間的句法差異有關),使用STL.NET集合與STL集合基本上一模一樣。以下的控制臺示例程序聲明了一個vector對象,接著在集合中加入了一些其他不同類型的元素:
??
#include "stdafx.h"
#include <cliext/vector>
?
using namespace System;
using namespace cliext;
?
int main(array<System::String ^> ^args)
{
?? vector<Object^>^ v = gcnew vector<Object^>;
?? v->push_back(nullptr);??????? //第一個元素為空
?? v->push_back(gcnew Object()); //第二個元素為一個純對象
?? v->push_back(1);????????????? //第三個元素為裝箱的整數
?? v->push_back("Element Four"); //第四個元素為字符串
?? return 0;
}
?
???????? 以上代碼演示了STL.NET的一個重要特點:仍舊是非常熟悉的集合類,另一個特點是,可在一個集合中使用兩種不同的編程模型,這意味著如果要查找上述代碼中的整數1,可使用下列STL find算法:
??
//當作STL集合使用
bool containsOneSTL = find( v->begin( ), v->end( ), 1 ) != v->end();
?
???????? 另外,.NET中ICollection泛型接口也能用于實現同樣的邏輯:
?
//當作 .NET集合使用
bool containsOnedotNet = v->Contains(1);
?
???????? 這種可在同一集合類中同時使用STL和 .NET算法的能力——而無須復制內容或提供橋接函數——允許C++/CLI程序員對任何有關集合的操作,選擇最恰當的函數與庫。
????????? 有關STL.NET最后一個特點是,可為用C#或VB.NET編寫的 .NET程序集,無縫地提供其STL.NET集合。由于STL.NET集合實現了ICollection泛型接口,所以在類型安全上,再無任何損耗,再者,STL.NET集合使用了托管內存來存儲集合中的元素,因此,在與那些提供STL.NET集合的C++/CLI程序集互操作時,再無任何性能或代碼安全性方面的損耗。
??
?
???????? .NET王國C++程序員的入場券
???????? STL.NET代表了Visual C++產品的一個重要部分,其允許C++程序員利用他們現有的技能與經驗,盡早使用上帶成強大集合與算法的類庫,而不至于被快速成長的 .NET世界拒之門外。
????????? STL.NET作為一個光明的開端,將有助于C++在保持語言光榮傳統的同時,成為 .NET語言開發的第一類選擇。
總結
以上是生活随笔為你收集整理的结合泛型与模板的STL.NET的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: vs中配置文件读写
- 下一篇: 相对于通过木马传播方式获得的C++用户数