﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-snowell-文章分类-概述类</title><link>http://www.cppblog.com/snowell/category/5015.html</link><description /><language>zh-cn</language><lastBuildDate>Tue, 27 May 2008 19:24:13 GMT</lastBuildDate><pubDate>Tue, 27 May 2008 19:24:13 GMT</pubDate><ttl>60</ttl><item><title>什么是虚函数（转）</title><link>http://www.cppblog.com/snowell/articles/35511.html</link><dc:creator>snowell</dc:creator><author>snowell</author><pubDate>Tue, 30 Oct 2007 04:59:00 GMT</pubDate><guid>http://www.cppblog.com/snowell/articles/35511.html</guid><wfw:comment>http://www.cppblog.com/snowell/comments/35511.html</wfw:comment><comments>http://www.cppblog.com/snowell/articles/35511.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/snowell/comments/commentRss/35511.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/snowell/services/trackbacks/35511.html</trackback:ping><description><![CDATA[1. 虚函数的定义 <br>虚函数用来表现基类和派生类的成员函数之间的一种关系. <br>虚函数的定义在基类中进行,在需要定义为虚函数的成员函数的声明前冠以关键字 virtual. <br>基类中的某个成员函数被声明为虚函数后,此虚函数就可以在一个或多个派生类中被重新定义. <br>在派生类中重新定义时,其函数原型,包括返回类型,函数名,参数个数,参数类型及参数的先后顺序,都必须与基类中的原型完全相同. <br>虚函数是重载的一种表现形式,是一种动态的重载方式. <br>2. 为什么使用虚函数 <br>#include <br>class CBase{ <br>public: <br>void who( ) <br>{cout&lt;&lt;"this is the base class!\n";} <br>}; <br>class CDerive1 : public CBase{ <br>public: <br>void who( ) <br>{cout&lt;&lt;"this is the derive1 class!\n";} <br>}; <br>class CDerive2 : public CBase{ <br>public: <br>void who( ) <br>{cout&lt; who( ); <br>p = &amp;obj2; <br>p -&gt; who( ); <br>p = &amp;obj3; <br>p -&gt; who( ); <br>obj2.who( ); <br>obj3.who( ); <br>return 1; <br>} <br>运行结果: <br>this is the base class! <br>this is the base class! <br>this is the base class! <br>this is the derive1 class! <br>this is the derive2 class! <br>通过对象指针进行的普通成员函数调用,仅仅与指针的类型有关,而与此刻正指向什么对象无关.要想实现当指针指向不同对象时执行不同的操作,就必须将基类相应中的成员函数定义为虚函数. <br>3. 虚函数与重载函数的关系 <br>一般的重载函数,函数的返回类型及所带的参数必须至少有一样不完全相同,只需函数名相同即可. <br>基类中定义的虚函数在派生类中重新定义时,其函数原型,包括返回类型,函数名,参数个数,参数类型及参数的先后顺序,都必须与基类中的原型完全相同. <br>重载虚函数时,若与基类中的函数原型出现不同,系统将根据不同情况分别处理: <br>(1)仅仅返回类型不同,其余相同,系统会当作出错处理; <br>(2)函数原型不同,仅仅函数名相同,系统会认为是一般的函数重载,将丢失虚特性. <br>3.3.4 虚基类 <br>#include <br>class x{ <br>protected: <br>int a; <br>public: <br>void f ( ) ; <br>}; <br>class x1 : public x { <br>public: <br>x1( ){cout&lt;}; <br>class x2 : public x { <br>public: <br>x2( ){ cout&lt;}; <br>class y : public x1, public x2{ <br>public: <br>y( ){ cout&lt;}; <br>main( ) <br>{ <br>y obj; //error <br>obj . f ( ) ; //error <br>return ; <br>} <br>二义性错误 <br>非虚基类的类层次 <br>虚基类的类层次 <br>当在多条继承路径上有一个公共的基类,在这些路径中的某几条汇合处,这个公共的基类就会产生多个实例(或多个副本),若只想保存这个基类的一个实例,可以将这个公共基类说明为虚基类. <br>class x1 : virtual public x <br>{ <br>// &#8230; &#8230; <br>}; <br>class x2 : virtual public x <br>{ <br>// &#8230; &#8230; <br>}; <br>虚基类的初始化 <br>虚基类的初始化与一般多继承的初始化在语法上是一样的,但构造函数的调用次序不同. <br>派生类构造函数的调用次序有三个原则: <br>(1) 虚基类的构造函数在非虚基类之前调用; <br>(2) 若同一层次中包含多个虚基类,这些虚基类的构造函数按它们说明的次序调用; <br>(3) 若虚基类由非虚基类派生而来,则仍先调用基类构造函数,再调用派生类的构造函数. <br><br><br>纯虚函数 <br>仅仅用来为要从基类中派生的函数占据一个位置。 <br>纯虚函数在基类中没有定义，它们被初始化为0。 <br>任何用纯虚函数派生的类，都要自己提供该函数的具体实现。 <br><br>定义纯虚函数 <br>virtual void myMethod(void) = 0;</ca> 
<img src ="http://www.cppblog.com/snowell/aggbug/35511.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/snowell/" target="_blank">snowell</a> 2007-10-30 12:59 <a href="http://www.cppblog.com/snowell/articles/35511.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C#（C sharp）简介（转）</title><link>http://www.cppblog.com/snowell/articles/30970.html</link><dc:creator>snowell</dc:creator><author>snowell</author><pubDate>Mon, 27 Aug 2007 12:17:00 GMT</pubDate><guid>http://www.cppblog.com/snowell/articles/30970.html</guid><wfw:comment>http://www.cppblog.com/snowell/comments/30970.html</wfw:comment><comments>http://www.cppblog.com/snowell/articles/30970.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/snowell/comments/commentRss/30970.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/snowell/services/trackbacks/30970.html</trackback:ping><description><![CDATA[<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;C sharp(又被简称为&#8220;C#&#8221;)是微软公司在去年六月发布的一种新的编程语言,并定于在微软职业开发者论坛(PDC)上登台亮相.C#是微</p>
<p>软公司研究员Anders Hejlsberg的最新成果.C#看起来与Java有着惊人的相似;它包括了诸如单一继承,界面,与Java几乎同样的语法,和</p>
<p>编译成中间代码再运行的过程.但是C#与Java有着明显的不同,它借鉴了Delphi的一个特点,与COM(组件对象模型)是直接集成的,而且它</p>
<p>是微软公司.NET windows网络框架的主角. </p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在本文中,我将考察创建一种新计算机语言的一般动机,并将特别指明是什么原因导致了C#的出现.然后我将介绍C#和它与Java,c,c++的</p>
<p>相似之处.其次我将讨论一些存在于Java和C#之间的高层次的,和基础的差别.我将以衡量在用多种语言开发大型应用程序的时候所需的</p>
<p>知识(或者对这种知识的缺乏程度)来结束本文,而这正是.NET和C#的一个主要战略.目前,C#和.NET还只能以C#语言规则,以及Windows </p>
<p>2000的一个"d预览版本",还有MSDN上迅速增多的文档集子的形式获得(还没有最终定型). </p>
<p>微软c#语言定义主要是从C和C++继承而来的,而且语言中的许多元素也反映了这一点.C#在设计者从C++继承的可选选项方面比Java要广</p>
<p>泛一些(比如说structs),它还增加了自己新的特点(比方说源代码版本定义).但它还太不成熟,不可能挤垮Java.C#还需要进化成一种开</p>
<p>发者能够接受和采用的语言.而微软当前为它的这种新语言大造声势也是值得注意的.目前大家的反应是:"这是对Java的反击." </p>
<p>C#更象Java一些,虽然微软在这个问题上保持沉默.这也是意料中的事情,我觉得,因为Java近来很成功而使用Java的公司都报告说它们</p>
<p>在生产效率上比C++获得了提高. </p>
<p>Java所带来的巨大影响和大家对它的广泛接受已经由工作于这种语言和平台之上的程序员数量明显的说明了(估计世界范围内共有两百</p>
<p>五十万程序员使用Java).由这种语言写成的应用程序的数量是令人惊讶的并已经渗透了每一个级别的计算,包括无线计算和移动电话(</p>
<p>比如日本发明的Java电话).C#能够在用户领域获得这样的礼遇吗?我们必须等待并观望,就象已经由SSI公司的CEO和主席Kalpathi S. </p>
<p>Suresh指出来的那样,"我发现所有这些都是渐进的.如果C#不存在,我们总能回到Java或C和C++.这些都不完全是新技术;它们在更大的</p>
<p>意义上来说只是大公司制造的市场噱头.我们必须给他们时间安顿下来看看这些是不是真的对IT工业有什么影响." </p>
<p>C#从Java继承而来的特点 </p>
<p>类:在C#中类的申明与Java很相似.这是合理的因为经验告诉我们Java模型工作得很好.Java的关键字import已经被替换成using,它起到</p>
<p>了同样的作用.一个类开始执行的起点是静态方法Main().下面的Hello World程序展示了基本的形式: </p>
<p>using System; </p>
<p>class Hello { </p>
<p>static void Main() { </p>
<p>Console.WriteLine("Hello, world"); </p>
<p>} </p>
<p>} </p>
<p>在这个例子中,System这个名字指向一个包括了基本C#实用类集合的命名空间(namespace).这个命名空间包括了Console类,它在这个例</p>
<p>子中被用来输出一个字符串.类可以是抽象的和不可继承的:一个被申明成abstract的类不能被实例化;它只能被用做一个基类.C#关键</p>
<p>字lock就象Java关键字final,它申明一个类不是抽象的,但是它也不能被用做另一个类的基类.界面:就象在Java中一样,一个界面是一</p>
<p>组方法集合的抽象定义.当一个类或结构体实现一个界面的时候,它必须实现这个界面中定义的所有方法.一个单一的类可以实现几个界</p>
<p>面.也许以后会出现一些微妙的差别,但是这个特点看起来与Java相比没有变化.布尔运算:条件表达式的结果是布尔数据类型,布尔数据</p>
<p>类型是这种语言中独立的一种数据类型.从布尔类型到其他类型没有直接的转换过程.布尔常量true和false是C#中的关键字.错误处理:</p>
<p>如Java中那样,通过抛出和捕捉异常对象来管理错误处理过程.内存管理:由底层.NET框架进行自动内存垃圾回收. </p>
<p>C#从C和C++继承的特点 </p>
<p>编译:程序直接编译成标准的二进制可执行形式.如果前面的Hello World程序被保存成一个文本文件并被命名为Hello.cs,它将被编译</p>
<p>成命名Hello.exe的可执行程序. </p>
<p>结构体:一个C#的结构体与C++的结构体是相似的,因为它能够包含数据申明和方法.但是,不象C++,C#结构体与类是不同的而且不支持继</p>
<p>承.但是,与Java相同的是,一个结构体可以实现界面. </p>
<p>预编译:C#中存在预编译指令支持条件编译,警告,错误报告和编译行控制.可用的预编译指令有: </p>
<p>#define </p>
<p>#undef </p>
<p>#if </p>
<p>#elif </p>
<p>#else </p>
<p>#endif </p>
<p>#warning </p>
<p>#error </p>
<p>#line [] </p>
<p>没有了#include 伪指令.你无法再用#define 语句对符号赋值,所以就不存在源代码替换的概念--这些符号只能用在#if和#elif伪指令</p>
<p>里.在#line伪指令里的数字(和可选的名字)能够修改行号还有#warning和#error输出结果的文件名. </p>
<p>操作符重载:一些操作符能够被重载,而另一些则不能.特别的是,没有一个赋值运算符能够被重载.能够被被重载的单目操作符是: </p>
<p>+ - ! ~ ++ -- true false </p>
<p>能够被重载的二元运算符是: </p>
<p>+ - * / % &amp; | ^ &lt;&lt; &gt;&gt; == != &gt; &lt; &gt;= &lt;= </p>
<p>C#独有的特点 </p>
<p>C#最引人入胜的地方是它和Java的不同,而不是相似的地方.这一节(和这个系列第二部分的大部分地方)讲述了C#实现的和Java不同的</p>
<p>地方或者Java根本没有的特点. </p>
<p>中间代码:微软在用户选择何时MSIL应该编译成机器码的时候是留了很大的余地.微软公司很小心的声称MSIL不是解释性的,而是被编译</p>
<p>成了机器码.它也明白许多--如果不是大多数的话--程序员认为Java程序要不可避免的比C编写的任何东西都要慢.而这种实现方式决定</p>
<p>了基于MSIL的程序(指的是用C#,Visual Basic,"Managed C++"--C++的一个符合CLS的版本--等语言编写的程序)将在性能上超过"解释</p>
<p>性的"Java代码.当然,这一点还需要得到事实证明,因为C#和其他生成MSIL的编译器还没有发布.但是Java JIT编译器的普遍存在使得</p>
<p>Java和C#在性能上相对相同.象"C#是编译语言而Java是解释性的,"之类的声明只是商业技巧.Java的中间代码和MSIL都是中间的汇编形</p>
<p>式的语言,它们在运行时或其它的时候被编译成机器代码. </p>
<p>命名空间中的申明:当你创建一个程序的时候,你在一个命名空间里创建了一个或多个类.同在这个命名空间里(在类的外面)你还有可能</p>
<p>声明界面,枚举类型和结构体.必须使用using关键字来引用其他命名空间的内容. </p>
<p>基本的数据类型:C#拥有比C,C++或者Java更广泛的数据类型.这些类型是bool, byte, ubyte, short, ushort, int, uint, long, </p>
<p>ulong, float, double,和decimal.象Java一样,所有这些类型都有一个固定的大小.又象C和C++一样,每个数据类型都有有符号和无符</p>
<p>号两种类型.与Java相同的是,一个字符变量包含的是一个16位的Unicode字符.C#新的数据类型是decimal数据类型,对于货币数据,它能</p>
<p>存放28位10进制数字. </p>
<p>两个基本类:一个名叫object的类是所有其他类的基类.而一个名叫string的类也象object一样是这个语言的一部分.作为语言的一部分</p>
<p>存在意味着编译器有可能使用它--无论何时你在程序中写入一句带引号的字符串,编译器会创建一个string对象来保存它. </p>
<p>参数传递:方法可以被声明接受可变数目的参数.缺省的参数传递方法是对基本数据类型进行值传递.ref关键字可以用来强迫一个变量</p>
<p>通过引用传递,这使得一个变量可以接受一个返回值.out关键字也能声明引用传递过程,与ref不同的地方是,它指明这个参数并不需要</p>
<p>初始值. </p>
<p>与COM的集成:C#对Windows程序最大的卖点可能就是它与COM的无缝集成了,COM就是微软的Win32组件技术.实际上,最终有可能在任</p>
<p>何.NET语言里编写COM客户和服务器端.C#编写的类可以子类化一个以存在的COM组件;生成的类也能被作为一个COM组件使用,然后又能</p>
<p>使用,比方说,JScript语言子类化它从而得到第三个COM组件.这种现象的结果是导致了一个运行环境的产生,在这个环境里的组件是网</p>
<p>络服务,可用用任何.NET语言子类化. </p>
<p>索引下标:一个索引与属性除了不使用属性名来引用类成员而是用一个方括号中的数字来匿名引用(就象用数组下标一样)以外是相似的</p>
<p>. </p>
<p>public class ListBox: Control { </p>
<p>private string[] items; </p>
<p>public string this[int index] { </p>
<p>get { </p>
<p>return items[index]; </p>
<p>} </p>
<p>set { </p>
<p>items[index] = value; </p>
<p>Repaint(); </p>
<p>} </p>
<p>} </p>
<p>} </p>
<p>可以用一个循环器来匿名引用字符串内部数组成员,就象下面这样: </p>
<p>ListBox listBox = ...; </p>
<p>listBox[0] = "hello"; </p>
<p>Console.WriteLine(listBox[0]); </p>
<p>代理和反馈:一个代理对象包括了访问一个特定对象的特定方法所需的信息.只要把它当成一个聪明的方法指针就行了.代理对象可以被</p>
<p>移动到另一个地方,然后可以通过访问它来对已存在的方法进行类型安全的调用.一个反馈方法是代理的特例.event关键字用在将在事</p>
<p>件发生的时候被当成代理调用的方法声明中.&nbsp; <br>（转自百度百科，贡献者：suffersky ）</p>
<img src ="http://www.cppblog.com/snowell/aggbug/30970.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/snowell/" target="_blank">snowell</a> 2007-08-27 20:17 <a href="http://www.cppblog.com/snowell/articles/30970.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>STL简介（转）</title><link>http://www.cppblog.com/snowell/articles/30963.html</link><dc:creator>snowell</dc:creator><author>snowell</author><pubDate>Mon, 27 Aug 2007 11:31:00 GMT</pubDate><guid>http://www.cppblog.com/snowell/articles/30963.html</guid><wfw:comment>http://www.cppblog.com/snowell/comments/30963.html</wfw:comment><comments>http://www.cppblog.com/snowell/articles/30963.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/snowell/comments/commentRss/30963.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/snowell/services/trackbacks/30963.html</trackback:ping><description><![CDATA[<p>一、STL简介<br>STL（Standard Template Library，标准模板库)是惠普实验室开发的一系列软件的统称。它是由Alexander Stepanov、Meng Lee和David R Musser在惠普实验室工作时所开发出来的。现在虽说它主要出现在C++中，但在被引入C++之前该技术就已经存在了很长的一段时间。</p>
<p>STL的代码从广义上讲分为三类：algorithm（算法）、container（容器）和iterator（迭代器），几乎所有的代码都采用了模板类和模版函数的方式，这相比于传统的由函数和类组成的库来说提供了更好的代码重用机会。在C++标准中，STL被组织为下面的13个头文件：&lt;algorithm&gt;、&lt;deque&gt;、&lt;functional&gt;、&lt;iterator&gt;、&lt;vector&gt;、&lt;list&gt;、&lt;map&gt;、&lt;memory&gt;、&lt;numeric&gt;、&lt;queue&gt;、&lt;set&gt;、&lt;stack&gt;和&lt;utility&gt;。以下笔者就简单介绍一下STL各个部分的主要特点。</p>
<p>二、算法<br>大家都能取得的一个共识是函数库对数据类型的选择对其可重用性起着至关重要的作用。举例来说，一个求方根的函数，在使用浮点数作为其参数类型的情况下的可重用性肯定比使用整型作为它的参数类性要高。而C++通过模板的机制允许推迟对某些类型的选择，直到真正想使用模板或者说对模板进行特化的时候，STL就利用了这一点提供了相当多的有用算法。它是在一个有效的框架中完成这些算法的——你可以将所有的类型划分为少数的几类，然后就可以在模版的参数中使用一种类型替换掉同一种类中的其他类型。</p>
<p>STL提供了大约100个实现算法的模版函数，比如算法for_each将为指定序列中的每一个元素调用指定的函数，stable_sort以你所指定的规则对序列进行稳定性排序等等。这样一来，只要我们熟悉了STL之后，许多代码可以被大大的化简，只需要通过调用一两个算法模板，就可以完成所需要的功能并大大地提升效率。</p>
<p>算法部分主要由头文件&lt;algorithm&gt;，&lt;numeric&gt;和&lt;functional&gt;组成。&lt;algorithm&gt;是所有STL头文件中最大的一个（尽管它很好理解），它是由一大堆模版函数组成的，可以认为每个函数在很大程度上都是独立的，其中常用到的功能范围涉及到比较、交换、查找、遍历操作、复制、修改、移除、反转、排序、合并等等。&lt;numeric&gt;体积很小，只包括几个在序列上面进行简单数学运算的模板函数，包括加法和乘法在序列上的一些操作。&lt;functional&gt;中则定义了一些模板类，用以声明函数对象。</p>
<p>三、容器<br>在实际的开发过程中，数据结构本身的重要性不会逊于操作于数据结构的算法的重要性，当程序中存在着对时间要求很高的部分时，数据结构的选择就显得更加重要。</p>
<p>经典的数据结构数量有限，但是我们常常重复着一些为了实现向量、链表等结构而编写的代码，这些代码都十分相似，只是为了适应不同数据的变化而在细节上有所出入。STL容器就为我们提供了这样的方便，它允许我们重复利用已有的实现构造自己的特定类型下的数据结构，通过设置一些模版类，STL容器对最常用的数据结构提供了支持，这些模板的参数允许我们指定容器中元素的数据类型，可以将我们许多重复而乏味的工作简化。</p>
<p>容器部分主要由头文件&lt;vector&gt;,&lt;list&gt;,&lt;deque&gt;,&lt;set&gt;,&lt;map&gt;,&lt;stack&gt;和&lt;queue&gt;组成。对于常用的一些容器和容器适配器（可以看作由其它容器实现的容器），可以通过下表总结一下它们和相应头文件的对应关系。</p>
<p>数据结构&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 描述&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 实现头文件 <br>向量(vector)&nbsp; 连续存储的元素&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;vector&gt; <br>列表(list)&nbsp;&nbsp;&nbsp; 由节点组成的双向链表，每个结点包含着一个元素&nbsp;&nbsp;&nbsp;&nbsp; &lt;list&gt; <br>双队列(deque) 连续存储的指向不同元素的指针所组成的数组&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;deque&gt; <br>集合(set)&nbsp;&nbsp;&nbsp;&nbsp; 由节点组成的红黑树，每个节点都包含着一个元素，节点之间以某种作用于元素对的谓词排列，没有两个不同的元素能够拥有相同的次序&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;set&gt; <br>多重集合(multiset) 允许存在两个次序相等的元素的集合&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;set&gt; <br>栈(stack)&nbsp;&nbsp;&nbsp;&nbsp; 后进先出的值的排列&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;stack&gt; <br>队列(queue)&nbsp;&nbsp; 先进先出的执的排列&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;queue&gt; <br>优先队列(priority_queue) 元素的次序是由作用于所存储的值对上的某种谓词决定的的一种队列&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;queue&gt; <br>映射(map)&nbsp;&nbsp;&nbsp;&nbsp; 由{键，值}对组成的集合，以某种作用于键对上的谓词排列 &lt;map&gt; <br>多重映射(multimap) 允许键对有相等的次序的映射&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;map&gt; </p>
<p>四、迭代器<br>下面要说的迭代器从作用上来说是最基本的部分，可是理解起来比前两者都要费力一些（至少笔者是这样）。软件设计有一个基本原则，所有的问题都可以通过引进一个间接层来简化，这种简化在STL中就是用迭代器来完成的。概括来说，迭代器在STL中用来将算法和容器联系起来，起着一种黏和剂的作用。几乎STL提供的所有算法都是通过迭代器存取元素序列进行工作的，每一个容器都定义了其本身所专有的迭代器，用以存取容器中的元素。</p>
<p>迭代器部分主要由头文件&lt;utility&gt;,&lt;iterator&gt;和&lt;memory&gt;组成。&lt;utility&gt;是一个很小的头文件，它包括了贯穿使用在STL中的几个模板的声明，&lt;iterator&gt;中提供了迭代器使用的许多方法，而对于&lt;memory&gt;的描述则十分的困难，它以不同寻常的方式为容器中的元素分配存储空间，同时也为某些算法执行期间产生的临时对象提供机制,&lt;memory&gt;中的主要部分是模板类allocator，它负责产生所有容器中的默认分配器。</p>
<p>五、对初学者学习STL的一点建议<br>对于之前不太了解STL的读者来说，上面的文字只是十分概括地描述了一下STL的框架，对您理解STL的机制乃至使用STL所起到的帮助微乎甚微，这不光是因为深入STL需要对C++的高级应用有比较全面的了解，更因为STL的三个部分算法、容器和迭代器三部分是互相牵制或者说是紧密结合的。从概念上讲最基础的部分是迭代器，可是直接学习迭代器会遇到许多抽象枯燥和繁琐的细节，然而不真正理解迭代器又是无法直接进入另两部分的学习的（至少对剖析源码来说是这样）。可以说，适应STL处理问题的方法是需要花费一定的时间的，但是以此为代价，STL取得了一种十分可贵的独立性，它通过迭代器能在尽可能少地知道某种数据结构的情况下完成对这一结构的运算，所以下决心钻研STL的朋友们千万不要被一时的困难击倒。其实STL运用的模式相对统一，只要适应了它，从一个STL工具到另一个工具，都不会有什么大的变化。</p>
<p>对于STL的使用，也普遍存在着两种观点。第一种认为STL的最大作用在于充当经典的数据结构和算法教材，因为它的源代码涉及了许多具体实现方面的问题。第二种则认为STL的初衷乃是为了简化设计，避免重复劳动，提高编程效率，因此应该是&#8220;应用至上&#8221;的，对于源代码则不必深究。笔者则认为分析源代码和应用并不矛盾，通过分析源代码也能提高我们对其应用的理解，当然根据具体的目的也可以有不同的侧重。</p>
<p>最后要说的是，STL是ANSI/ISO C++标准的一部分，所以对于一个可以有多种C++实现的过程，首先考虑的应该是STL提供的模板（高效且可移植性好），其次才是各个厂商各自相应的库（高效但可移植性不好）以及自己去编写代码（可移植性好但低效）。 <br></p>
<img src ="http://www.cppblog.com/snowell/aggbug/30963.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/snowell/" target="_blank">snowell</a> 2007-08-27 19:31 <a href="http://www.cppblog.com/snowell/articles/30963.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>