首页 > 编程 > .NET > 正文

结合泛型与模板的STL.NET探索

2024-07-10 13:09:16
字体:
来源:转载
供稿:网友
  开始之前,先来看一个笑话,当问一个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集合的内容。虽然这种层次上的集成非常之浅,但在许多受限情况下证实非常有用。基于同样的主旨,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语言开发的第一类选择。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表