技术开发 频道

C++/CLI:第一流的CLI语言(4)

  STL/CLR

  当大量使用STL的C++开发者转向.NET1/1.1时一定感觉非常别扭,他们中的许多可能会放弃并转回到原来的本机编码。从技术上讲,你能结合.NET类型(using gcroot)使用本机STL,但是产生的结果代码可能相当低效,更不用说是丑陋了:

std::vector< gcroot<IntPtr> >* m_vec_hglobal; //... for each(gcroot<IntPtr> ptr in *m_vec_hglobal) { Marshal::FreeHGlobal(ptr);}
  大概VC++小组考虑到了这些并决定在Whidbey以后,他们会提供STL.NET(或STL/CLR)并可以单独从网上下载。
 
  你可能问为什么?Stan Lippman,在他的MSDN文章(STL.NET Primer)中给出了3条原因:
 
  ·可扩展性--STL设计把算法和容器隔离到自己的应用空间-也就是你可以有一组容器和一组算法,并且你能在任何一个容器上使用这些算法;同时你能在任何一个算法中使用这些容器。因此,如果你添加一种新的算法,你能在任何一种容器中使用它;同样,一个新的容器也可以与现有算法配合使用。
 
  ·统一性--所有核心C++开发者集中在一起,汇集起他们精妙的STL专长,再使用他们的专长则轻车熟路。要较好地使用STL需要花费时间-然而一旦你掌握了它,你就有了在.NET世界中使用你的技巧的明显优势。不是吗?
 
  ·性能--STL.NET通过使用实现泛型接口的托管模板实现。并且既然它的核心已用C++和托管模板编码,可以期盼它比在BCL上使用的泛型容器更具有性能优势。
 
  使用过STL的人不需要任何示范,所以下面代码有益于以前没有使用过STL的人。
vector<String^> vecstr; vecstr.push_back("wally"); vecstr.push_back("nish"); vecstr.push_back("smitha"); vecstr.push_back("nivi"); deque<String^> deqstr; deqstr.push_back("wally"); deqstr.push_back("nish"); deqstr.push_back("smitha"); deqstr.push_back("nivi");
  我使用了两个STL.NET容器-vector和deque,并装满两个容器,使其看起来相同(在两个容器中都使用了push_back)。现在,我将在两个容器上使用replace算法-我们再次看到,这些代码是很相同的。
replace(vecstr.begin(), vecstr.end(), gcnew String("nish"), gcnew String("jambo")); replace(deqstr.begin(), deqstr.end(), gcnew String("nish"), gcnew String("chris"));
  这里特别要注意的是我使用了"同样"的算法--replace并在两个不同STL容器上使用相同的函数调用。这是当Stan谈及"可扩展性"时的意思。下面我用一个简单函数来证明:
template<typename ForwardIterator> void Capitalize( ForwardIterator first,ForwardIterator end) { for(ForwardIterator it = first; it < end; it++) *it = (*it)->ToUpper(); }
  它遍历一个System::String^容器并把其中的每个字符串转化为大写。
Capitalize(vecstr.begin(), vecstr.end()); Capitalize(deqstr.begin(), deqstr.end()); for(vector<String^>::iterator it = vecstr.begin(); it < vecstr.end(); it++) Console::WriteLine(*it); Console::WriteLine(); for(deque<String^>::iterator it = deqstr.begin(); it < deqstr.end(); it++) Console::WriteLine(*it);
  上面我的算法能够与vector和deque容器工作良好。至此,不再细谈;否则,guru站上的STL爱好者们会对我群起攻击,而非STL人可能感到厌烦。如果你还没使用过STL,可以参考有关资料。

 

0
相关文章