﻿<?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++博客-舞影凌乱-随笔分类-C/C++基础知识</title><link>http://www.cppblog.com/lovefeel2004/category/11592.html</link><description>专注C/C++，Linux</description><language>zh-cn</language><lastBuildDate>Thu, 24 Jun 2010 07:36:45 GMT</lastBuildDate><pubDate>Thu, 24 Jun 2010 07:36:45 GMT</pubDate><ttl>60</ttl><item><title>STL vector 容器介绍</title><link>http://www.cppblog.com/lovefeel2004/archive/2010/06/23/118556.html</link><dc:creator>幽梦新影</dc:creator><author>幽梦新影</author><pubDate>Wed, 23 Jun 2010 05:56:00 GMT</pubDate><guid>http://www.cppblog.com/lovefeel2004/archive/2010/06/23/118556.html</guid><wfw:comment>http://www.cppblog.com/lovefeel2004/comments/118556.html</wfw:comment><comments>http://www.cppblog.com/lovefeel2004/archive/2010/06/23/118556.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lovefeel2004/comments/commentRss/118556.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lovefeel2004/services/trackbacks/118556.html</trackback:ping><description><![CDATA[<p><strong><span>介绍</span></strong><strong></strong></p>
<p><span>这篇文章的目的是为了介绍</span><span>std::vector</span><span>，如何恰当地使用它们的成员函数等操作。本文中还讨论了条件函数和函数指针在迭代算法中使用，如在</span><span>remove_if()</span><span>和</span><span>for_each()</span><span>中的使用。通过阅读这篇文章读者应该能够有效地使用</span><span>vector</span><span>容器，而且应该不会再去使用</span><span>C</span><span>类型的动态数组了。</span></p>
<p><strong>&nbsp;</strong></p>
<p><strong><span>Vector</span></strong><strong><span>总览</span></strong><strong></strong></p>
<p><span>vector</span><span>是</span><span>C++</span><span>标准模板库中的部分内容，它是一个多功能的，能够操作多种数据结构和算法的模板类和函数库。</span><span>vector</span><span>之所以被认为是一个容器，是因为它能够像容器一样存放各种类型的对象，简单地说，</span><span>vector</span><span>是一个能够存放任意类型的动态数组，能够增加和压缩数据。</span></p>
<p><span>为了可以使用</span><span>vector</span><span>，必须在你的头文件中包含下面的代码：</span><strong></strong></p>
<table cellSpacing=0 cellPadding=0 border=0>
    <tbody>
        <tr>
            <td vAlign=top width=528>
            <p><span>#</span><span>include</span><span> &lt;vector&gt;</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p><span>vector</span><span>属于</span><span>std</span><span>命名域的，因此需要通过命名限定，如下完成你的代码：</span><strong></strong></p>
<table cellSpacing=0 cellPadding=0 border=0>
    <tbody>
        <tr>
            <td vAlign=top width=528>
            <p><span>using</span><span> std::vector;</span></p>
            <p><span>vector&lt;</span><span>int</span><span>&gt; vInts;</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p><span>或者连在一起，使用全名：</span><strong></strong></p>
<table cellSpacing=0 cellPadding=0 border=0>
    <tbody>
        <tr>
            <td vAlign=top width=528>
            <p><span>std::vector&lt;</span><span>int</span><span>&gt; vInts;</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p><span>建议使用全局的命名域方式：</span><strong></strong></p>
<table cellSpacing=0 cellPadding=0 border=0>
    <tbody>
        <tr>
            <td vAlign=top width=528>
            <p><span>using</span><span> </span><span>namespace</span><span> std;</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p><span>在后面的操作中全局的命名域方式会造成一些问题。</span><span>vector</span><span>容器提供了很多接口，在下面的表中列出</span><span>vector</span><span>的成员函数和操作。</span></p>
<p><strong>&nbsp;</strong></p>
<p><strong><span>Vector</span></strong><strong><span>成员函数</span></strong><strong></strong></p>
<div align=center>
<table cellSpacing=1 cellPadding=0 width="90%" border=1>
    <tbody>
        <tr>
            <td width="33%">
            <p><span>函数</span></p>
            </td>
            <td width="66%">
            <p><span>表述</span></p>
            </td>
        </tr>
        <tr>
            <td width="33%">
            <p><span>c.assign(beg,end)</span></p>
            <p><span>c.assign(n,elem)</span></p>
            </td>
            <td width="66%">
            <p><span>将</span><span>[beg; end)</span><span>区间中的数据赋值给</span><span>c</span><span>。</span></p>
            <p><span>将</span><span>n</span><span>个</span><span>elem</span><span>的拷贝赋值给</span><span>c</span><span>。</span></p>
            </td>
        </tr>
        <tr>
            <td width="33%">
            <p><span>c.at(idx)</span></p>
            </td>
            <td width="66%">
            <p><span>传回索引</span><span>idx</span><span>所指的数据，如果</span><span>idx</span><span>越界，抛出</span><span>out_of_range</span><span>。</span></p>
            </td>
        </tr>
        <tr>
            <td width="33%">
            <p><span>c.back()</span></p>
            </td>
            <td width="66%">
            <p><span>传回最后一个数据，不检查这个数据是否存在。</span></p>
            </td>
        </tr>
        <tr>
            <td width="33%">
            <p><span>c.begin()</span></p>
            </td>
            <td width="66%">
            <p><span>传回迭代器重的可一个数据。</span></p>
            </td>
        </tr>
        <tr>
            <td width="33%">
            <p><span>c.capacity()</span></p>
            </td>
            <td width="66%">
            <p><span>返回容器中数据个数。</span></p>
            </td>
        </tr>
        <tr>
            <td width="33%">
            <p><span>c.clear()</span></p>
            </td>
            <td width="66%">
            <p><span>移除容器中所有数据。</span></p>
            </td>
        </tr>
        <tr>
            <td width="33%">
            <p><span>c.empty()</span></p>
            </td>
            <td width="66%">
            <p><span>判断容器是否为空。</span></p>
            </td>
        </tr>
        <tr>
            <td width="33%">
            <p><span>c.end()</span></p>
            </td>
            <td width="66%">
            <p><span>指向迭代器中的最后一个数据地址。</span></p>
            </td>
        </tr>
        <tr>
            <td width="33%">
            <p><span>c.erase(pos)</span></p>
            <p><span>c.erase(beg,end)</span></p>
            </td>
            <td width="66%">
            <p><span>删除</span><span>pos</span><span>位置的数据，传回下一个数据的位置。</span></p>
            <p><span>删除</span><span>[beg,end)</span><span>区间的数据，传回下一个数据的位置</span><span>。</span></p>
            </td>
        </tr>
        <tr>
            <td width="33%">
            <p><span>c.front()</span></p>
            </td>
            <td width="66%">
            <p><span>传回地一个数据。</span></p>
            </td>
        </tr>
        <tr>
            <td width="33%">
            <p><span>get_allocator</span></p>
            </td>
            <td width="66%">
            <p><span>使用构造函数返回一个拷贝。</span></p>
            </td>
        </tr>
        <tr>
            <td width="33%">
            <p><span>c.insert(pos,elem) </span></p>
            <p><span>c.insert(pos,n,elem)</span></p>
            <p><span>c.insert(pos,beg,end)</span></p>
            </td>
            <td width="66%">
            <p><span>在</span><span>pos</span><span>位置插入一个</span><span>elem</span><span>拷贝，传回新数据位置。</span></p>
            <p><span>在</span><span>pos</span><span>位置插入</span><span>n</span><span>个</span><span>elem</span><span>数据。无返回值。</span></p>
            <p><span>在</span><span>pos</span><span>位置插入在</span><span>[beg,end)</span><span>区间的数据。无返回值。</span></p>
            </td>
        </tr>
        <tr>
            <td width="33%">
            <p><span>c.max_size()</span></p>
            </td>
            <td width="66%">
            <p><span>返回容器中最大数据的数量。</span></p>
            </td>
        </tr>
        <tr>
            <td width="33%">
            <p><span>c.pop_back()</span></p>
            </td>
            <td width="66%">
            <p><span>删除最后一个数据。</span></p>
            </td>
        </tr>
        <tr>
            <td width="33%">
            <p><span>c.push_back(elem)</span></p>
            </td>
            <td width="66%">
            <p><span>在尾部加入一个数据。</span></p>
            </td>
        </tr>
        <tr>
            <td width="33%">
            <p><span>c.rbegin()</span></p>
            </td>
            <td width="66%">
            <p><span>传回一个逆向队列的第一个数据。</span></p>
            </td>
        </tr>
        <tr>
            <td width="33%">
            <p><span>c.rend()</span></p>
            </td>
            <td width="66%">
            <p><span>传回一个逆向队列的最后一个数据的下一个位置。</span></p>
            </td>
        </tr>
        <tr>
            <td width="33%">
            <p><span>c.resize(num)</span></p>
            </td>
            <td width="66%">
            <p><span>重新指定队列的长度。</span></p>
            </td>
        </tr>
        <tr>
            <td width="33%">
            <p><span>c.reserve()</span></p>
            </td>
            <td width="66%">
            <p><span>保留适当的容量。</span></p>
            </td>
        </tr>
        <tr>
            <td width="33%">
            <p><span>c.size()</span></p>
            </td>
            <td width="66%">
            <p><span>返回容器中实际数据的个数。</span></p>
            </td>
        </tr>
        <tr>
            <td width="33%">
            <p><span>c1.swap(c2) </span></p>
            <p><span>swap(c1,c2)</span></p>
            </td>
            <td width="66%">
            <p><span>将</span><span>c1</span><span>和</span><span>c2</span><span>元素互换。</span></p>
            <p><span>同上操作。</span></p>
            </td>
        </tr>
        <tr>
            <td width="33%">
            <p><span>vector&lt;Elem&gt; c</span></p>
            <p><span>vector &lt;Elem&gt; c1(c2)</span></p>
            <p><span>vector &lt;Elem&gt; c(n)</span></p>
            <p><span>vector &lt;Elem&gt; c(n, elem)</span></p>
            <p><span>vector &lt;Elem&gt; c(beg,end)</span></p>
            <p><span>c.~ vector &lt;Elem&gt;()</span></p>
            </td>
            <td width="66%">
            <p><span>创建一个空的</span><span>vector</span><span>。</span></p>
            <p><span>复制一个</span><span>vector</span><span>。</span></p>
            <p><span>创建一个</span><span>vector</span><span>，含有</span><span>n</span><span>个数据，数据均已缺省构造产生</span><span>。</span></p>
            <p><span>创建一个含有</span><span>n</span><span>个</span><span>elem</span><span>拷贝的</span><span>vector</span><span>。</span></p>
            <p><span>创建一个以</span><span>[beg;end)</span><span>区间的</span><span>vector</span><span>。</span></p>
            <p><span>销毁所有数据，释放内存。</span></p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<p>&nbsp;</p>
<p><strong><span>Vector</span></strong><strong><span>操作</span></strong><strong></strong></p>
<div align=center>
<table cellSpacing=1 cellPadding=0 width="90%" border=1>
    <tbody>
        <tr>
            <td width="32%">
            <p align=left><span>函数</span></p>
            </td>
            <td width="66%">
            <p align=left><span>描述</span></p>
            </td>
        </tr>
        <tr>
            <td width="32%">
            <p><span>operator</span><span>[]</span><span> </span></p>
            </td>
            <td width="66%">
            <p><span>返回容器中指定位置的一个引用。</span></p>
            </td>
        </tr>
    </tbody>
</table>
</div>
<p><strong>&nbsp;</strong></p>
<p><strong><span>创建一个</span></strong><strong><span>vector</span></strong></p>
<p><span>vector</span><span>容器提供了多种创建方法，下面介绍几种常用的。</span></p>
<p><span>创建一个</span><span>Widget</span><span>类型的空的</span><span>vector</span><span>对象：</span><strong></strong></p>
<table cellSpacing=0 cellPadding=0 border=0>
    <tbody>
        <tr>
            <td vAlign=top width=528>
            <p><span>vector&lt;Widget&gt; vWidgets;</span></p>
            <p><span>//<span>&nbsp;&nbsp;&nbsp;&nbsp; </span>------</span></p>
            <p><span>//<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>|</span></p>
            <p><span>//<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>|- Since vector is a container, its member functions</span></p>
            <p><span>//<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>operate on iterators and the container itself so </span></p>
            <p><span>//<span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>it can hold objects of any type.</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p><span>创建一个包含</span><span>500</span><span>个</span><span>Widget</span><span>类型数据的</span><span>vector</span><span>：</span><strong></strong></p>
<table cellSpacing=0 cellPadding=0 border=0>
    <tbody>
        <tr>
            <td vAlign=top width=528>
            <p><span>vector&lt;Widget&gt; vWidgets(500);</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p><span>创建一个包含</span><span>500</span><span>个</span><span>Widget</span><span>类型数据的</span><span>vector</span><span>，并且都初始化为</span><span>0</span><span>：</span><strong></strong></p>
<table cellSpacing=0 cellPadding=0 border=0>
    <tbody>
        <tr>
            <td vAlign=top width=528>
            <p><span>vector&lt;Widget&gt; vWidgets(500, Widget(0));</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p><span>创建一个</span><span>Widget</span><span>的拷贝：</span><strong></strong></p>
<table cellSpacing=0 cellPadding=0 border=0>
    <tbody>
        <tr>
            <td vAlign=top width=528>
            <p><span>vector&lt;Widget&gt; vWidgetsFromAnother(vWidgets);</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><strong>&nbsp;</strong></p>
<p><strong><span>向</span></strong><strong><span>vector</span></strong><strong><span>添加一个数据</span></strong><strong></strong></p>
<p><span>vector</span><span>添加数据的缺省方法是</span><span>push_back()</span><span>。</span><span>push_back()</span><span>函数表示将数据添加到</span><span>vector</span><span>的尾部，并按需要来分配内存。例如：向</span><span>vector&lt;Widget&gt;</span><span>中添加</span><span>10</span><span>个数据，需要如下编写代码：</span><strong></strong></p>
<table cellSpacing=0 cellPadding=0 border=0>
    <tbody>
        <tr>
            <td vAlign=top width=528>
            <p><span>for</span><span>(int i= 0;i&lt;10; i++)</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp; </span>vWidgets.push_back(Widget(i));</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><strong>&nbsp;</strong></p>
<p><strong><span>获取</span></strong><strong><span>vector</span></strong><strong><span>中制定位置的数据</span></strong><strong></strong></p>
<p><span>很多时候我们不必要知道</span><span>vector</span><span>里面有多少数据，</span><span>vector</span><span>里面的数据是动态分配的，使用</span><span>push_back()</span><span>的一系列分配空间常常决定于文件或一些数据源。如果你想知道</span><span>vector</span><span>存放了多少数据，你可以使用</span><span>empty()</span><span>。获取</span><span>vector</span><span>的大小，可以使用</span><span>size()</span><span>。例如，如果你想获取一个</span><span>vector v</span><span>的大小，但不知道它是否为空，或者已经包含了数据，如果为空想设置为</span><span>-1</span><span>，你可以使用下面的代码实现：</span><strong></strong></p>
<table cellSpacing=0 cellPadding=0 border=0>
    <tbody>
        <tr>
            <td vAlign=top width=528>
            <p><span>int</span><span> nSize = v.empty() ? -1 : </span><span>static_cast</span><span>&lt;</span><span>int</span><span>&gt;(v.size());</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p><strong><span>访问</span></strong><strong><span>vector</span></strong><strong><span>中的数据</span></strong><strong></strong></p>
<p><span>使用两种方法来访问</span><span>vector</span><span>。</span></p>
<p><span><span>1、<span>&nbsp;&nbsp; </span></span></span><span>vector::at()</span></p>
<p><span><span>2、<span>&nbsp;&nbsp; </span></span></span><span>vector::operator[]</span></p>
<p><span>operator[]</span><span>主要是为了与</span><span>C</span><span>语言进行兼容。它可以像</span><span>C</span><span>语言数组一样操作。但</span><span>at()</span><span>是我们的首选，因为</span><span>at()</span><span>进行了边界检查，如果访问超过了</span><span>vector</span><span>的范围，将抛出一个例外。由于</span><span>operator[]</span><span>容易造成一些错误，所有我们很少用它，下面进行验证一下：</span></p>
<p><span>分析下面的代码：</span></p>
<table cellSpacing=0 cellPadding=0 border=0>
    <tbody>
        <tr>
            <td vAlign=top width=528>
            <p><span>vector&lt;</span><span>int</span><span>&gt; v;</span></p>
            <p><span>v.reserve(10);</span></p>
            <p>&nbsp;</p>
            <p><span>for</span><span>(</span><span>int</span><span> i=0; i&lt;7; i++)</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp; </span>v.push_back(i);</span></p>
            <p>&nbsp;</p>
            <p><span>try</span></p>
            <p><span>{</span></p>
            <p><span>&nbsp;</span><span>int</span><span> iVal1 = v[7];&nbsp;// not bounds checked - will not throw</span></p>
            <p><span>&nbsp;</span><span>int</span><span> iVal2 = v.at(7); // bounds checked - will throw if out of range</span></p>
            <p><span>}</span></p>
            <p><span>catch</span><span>(</span><span>const</span><span> exception&amp; e)</span></p>
            <p><span>{</span></p>
            <p><span>&nbsp;cout &lt;&lt; e.what();</span></p>
            <p><span>}</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p><span>我们使用</span><span>reserve()</span><span>分配了</span><span>10</span><span>个</span><span>int</span><span>型的空间，但并不没有初始化。如下图所示：<br></span></p>
<p align=center><img alt="" hspace=0 src="http://www.codeproject.com/vcpp/stl/std_vector/vector_01.gif" align=baseline border=0></p>
<p align=right><br></p>
<span>
<p><span>你可以在这个代码中尝试不同条件，观察它的结果，但是无论何时使用</span><span>at()</span><span>，都是正确的。</span></p>
<p><strong><span><font size=3>&nbsp;</font></span></strong></p>
<p><font size=3><strong><span>删除</span></strong><strong><span>vector</span></strong><strong><span>中的数据</span></strong><strong></strong></font></p>
<p><span>vector</span><span>能够非常容易地添加数据，也能很方便地取出数据，同样</span><span>vector</span><span>提供了</span><span>erase()</span><span>，</span><span>pop_back()</span><span>，</span><span>clear()</span><span>来删除数据，当你删除数据的时候，你应该知道要删除尾部的数据，或者是删除所有数据，还是个别的数据。在考虑删除等操作之前让我们静下来考虑一下在</span><span>STL</span><span>中的一些应用。</span><span> </span></p>
<p><strong><span><font size=3>&nbsp;</font></span></strong></p>
<p><font size=3><strong><span>Remove_if()</span></strong><strong><span>算法</span></strong><strong></strong></font></p>
<p><span>现在我们考虑操作里面的数据。如果要使用</span><span>remove_if()</span><span>，我们需要在头文件中包含如下代码：：</span><strong></strong></p>
<table cellSpacing=0 cellPadding=0 border=0>
    <tbody>
        <tr>
            <td vAlign=top width=528>
            <p><span>#</span><span>include</span><span> &lt;algorithm&gt;</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Remove_if()</span><span>有三个参数：</span></p>
<p><span><span>1、<span>&nbsp;&nbsp; </span></span></span><span>iterator _First</span><span>：指向第一个数据的迭代指针。</span></p>
<p><span><span>2、<span>&nbsp;&nbsp; </span></span></span><span>iterator _Last</span><span>：指向最后一个数据的迭代指针。</span></p>
<p><span><span>3、<span>&nbsp;&nbsp; </span></span></span><span>predicate _Pred</span><span>：一个可以对迭代操作的条件函数。</span></p>
<p><strong><span><font size=3>&nbsp;</font></span></strong></p>
<p><font size=3><strong><span>条件函数</span></strong><strong></strong></font></p>
<p><span>条件函数是一个按照用户定义的条件返回是或否的结果，是最基本的函数指针，或者是一个函数对象。这个函数对象需要支持所有的函数调用操作，重载</span><span>operator()()</span><span>操作。</span><span>remove_if()</span><span>是通过</span><span>unary_function</span><span>继承下来的，允许传递数据作为条件。</span></p>
<p><span>例如，假如你想从一个</span><span>vector&lt;CString&gt;</span><span>中删除匹配的数据，如果字串中包含了一个值，从这个值开始，从这个值结束。首先你应该建立一个数据结构来包含这些数据，类似代码如下：</span><strong></strong></p>
<table cellSpacing=0 cellPadding=0 border=0>
    <tbody>
        <tr>
            <td vAlign=top width=528>
            <p><span>#</span><span>include</span><span> &lt;functional&gt;</span></p>
            <p><span>enum</span><span> findmodes </span></p>
            <p><span>{</span></p>
            <p><span>&nbsp;FM_INVALID = 0,</span></p>
            <p><span>&nbsp;FM_IS,</span></p>
            <p><span>&nbsp;FM_STARTSWITH,</span></p>
            <p><span>&nbsp;FM_ENDSWITH,</span></p>
            <p><span>&nbsp;FM_CONTAINS</span></p>
            <p><span>};</span></p>
            <p><span>typedef</span><span> </span><span>struct</span><span> tagFindStr</span></p>
            <p><span>{</span></p>
            <p><span>&nbsp;UINT iMode;</span></p>
            <p><span>&nbsp;CString szMatchStr;</span></p>
            <p><span>} FindStr;</span></p>
            <p><span>typedef</span><span> FindStr* LPFINDSTR;</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p><span>然后处理条件判断：</span></p>
<table cellSpacing=0 cellPadding=0 border=0>
    <tbody>
        <tr>
            <td vAlign=top width=528>
            <p><span>class</span><span> FindMatchingString </span></p>
            <p><span><span>&nbsp;&nbsp; </span>&nbsp;: </span><span>public</span><span> std::unary_function&lt;CString, </span><span>bool</span><span>&gt; </span></p>
            <p><span>{</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp; </span></span></p>
            <p><span>public</span><span>: </span></p>
            <p><span>&nbsp;FindMatchingString(</span><span>const</span><span> LPFINDSTR lpFS) : m_lpFS(lpFS) {} </span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp; </span></span></p>
            <p><span>&nbsp;</span><span>bool</span><span> operator()(CString&amp; szStringToCompare) </span><span>const</span><span> </span></p>
            <p><span>&nbsp;{ </span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>bool</span><span> retVal = </span><span>false</span><span>;</span></p>
            <p>&nbsp;</p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>switch</span><span>(m_lpFS-&gt;iMode) </span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>case</span><span> FM_IS: </span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{ </span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>retVal = (szStringToCompare == m_lpFDD-&gt;szMatchStr); </span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>break</span><span>;</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>case</span><span> FM_STARTSWITH: </span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{ </span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>retVal = (szStringToCompare.Left(m_lpFDD-&gt;szMatchStr.GetLength())</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span><span>&nbsp;&nbsp;&nbsp;&nbsp;</span><span>&nbsp;&nbsp;</span>== m_lpFDD-&gt;szWindowTitle);</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>&nbsp;<span>&nbsp;&nbsp;&nbsp;</span></span><span>break</span><span>;</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>} </span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>case</span><span> FM_ENDSWITH: </span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>retVal = (szStringToCompare.Right(m_lpFDD-&gt;szMatchStr.GetLength()) </span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>== m_lpFDD-&gt;szMatchStr);</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>break</span><span>; </span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>} </span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp; </span>&nbsp;</span><span>case</span><span> FM_CONTAINS: </span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>{</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>retVal = (szStringToCompare.Find(m_lpFDD-&gt;szMatchStr) != -1);</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>break</span><span>; </span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span>}</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp; </span></span><span>return</span><span> retVal;</span></p>
            <p><span>&nbsp;}</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></p>
            <p><span>private</span><span>: </span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp; </span>LPFINDSTR m_lpFS;</span></p>
            <p><span>};</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p>&nbsp;</p>
<p><span>通过这个操作你可以从</span><span>vector</span><span>中有效地删除数据：</span></p>
<table cellSpacing=0 cellPadding=0 border=0>
    <tbody>
        <tr>
            <td vAlign=top width=528>
            <p><span>// remove all strings containing the value of </span></p>
            <p><span>// szRemove from vector&lt;CString&gt; vs.</span></p>
            <p>&nbsp;</p>
            <p><span>FindStr fs;</span></p>
            <p><span>fs.iMode = FM_CONTAINS;</span></p>
            <p><span>fs.szMatchStr = szRemove;</span></p>
            <p>&nbsp;</p>
            <p><span>vs.erase(std::remove_if(vs.begin(), vs.end(), FindMatchingString(&amp;fs)), vs.end());</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><strong><span><font size=3>&nbsp;</font></span></strong></p>
<p><font size=3><strong><span>Remove_if()</span></strong><strong><span>能做什么？</span></strong><strong></strong></font></p>
<p><span>你可能会疑惑，对于上面那个例子在调用</span><span>remove_if()</span><span>的时候还要使用</span><span>erase()</span><span>呢？这是因为大家并不熟悉</span><span>STL</span><span>中的算法。</span><span>Remove(),remove_if(</span><span>)</span><span>等所有的移出操作都是建立在一个迭代范围上的，那么不能操作容器中的数据。所以在使用</span><span>remove_if()</span><span>，实际上操作的时容器里数据的上面的。思考上面的例子：</span></p>
<p><span><span>1、<span>&nbsp;&nbsp; </span></span></span><span>szRemove</span><span> = &#8220;o&#8221;.</span></p>
<p><span><span>2、<span>&nbsp;&nbsp; </span></span></span><span>vs</span><span>见下面图表中的显示。<br></span></p>
<p align=center><img alt="" hspace=0 src="http://www.codeproject.com/vcpp/stl/std_vector/vector_02.gif" align=baseline border=0></p>
<p><span>观察这个结果，我们可以看到</span><span>remove_if()</span><span>实际上是根据条件对迭代地址进行了修改，在数据的后面存在一些残余的数据，那些需要删除的数据。剩下的数据的位置可能不是原来的数据，但他们是不知道的。</span></p>
<p><span>调用</span><span>erase()</span><span>来删除那些残余的数据。注意上面例子中通过</span><span>erase()</span><span>删除</span><span>remove_if()</span><span>的结果和</span><span>vs.enc()</span><span>范围的数据。</span><strong></strong></p>
<p><strong><span><font face="Times New Roman" size=3>&nbsp;</font></span></strong></p>
<p><font size=3><strong><span>压缩一个臃肿的</span></strong><strong><span><font face="Times New Roman">vector</font></span></strong></font></p>
<p><span>很多时候大量的删除数据，或者通过使用</span><span>reserve()</span><span>，结果</span><span>vector</span><span>的空间远远大于实际需要的。所有需要压缩</span><span>vector</span><span>到它实际的大小。</span><span>resize()</span><span>能够增加</span><span>vector</span><span>的大小。</span><span>Clear()</span><span>仅仅能够改变缓存的大小，所有的这些对于</span><span>vector</span><span>释放内存等九非常重要了。如何来解决这些问题呢，让我们来操作一下。</span></p>
<p><span>我们可以通过一个</span><span>vector</span><span>创建另一个</span><span>vector</span><span>。让我们看看这将发生什么。假定我们已经有一个</span><span>vector v</span><span>，它的内存大小为</span><span><font face="Times New Roman">1000</font></span><span>，当我们调用</span><span>size()</span><span>的时候，它的大小仅为</span><span><font face="Times New Roman">7</font></span><span>。我们浪费了大量的内存。让我们在它的基础上创建一个</span><span>vector</span><span>。</span><strong></strong></p>
<p>&#160;</p>
<table cellSpacing=0 cellPadding=0 border=0>
    <tbody>
        <tr>
            <td vAlign=top width=528>
            <p><span>std::vector&lt;CString&gt; vNew(v);</span></p>
            <p><span>cout &lt;&lt; vNew.capacity();</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><span><font face="Times New Roman">&nbsp;</font></span></p>
<p><span>vNew.capacity()</span><span>返回的是</span><span><font face="Times New Roman">7</font></span><span>。这说明新创建的只是根据实际大小来分配的空间。现在我们不想释放</span><span><font face="Times New Roman">v</font></span><span>，因为我们要在其它地方用到它，我们可以使用</span><span>swap()</span><span>将</span><span>v</span><span>和</span><span>vNew</span><span>互相交换一下？</span></p>
<p>&#160;</p>
<table cellSpacing=0 cellPadding=0 border=0>
    <tbody>
        <tr>
            <td vAlign=top width=528>
            <p><span><span>&nbsp;&nbsp;&nbsp; </span>vNew.swap(v);</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp; </span>cout &lt;&lt; vNew.capacity();</span></p>
            <p><span><span>&nbsp;&nbsp;&nbsp; </span>cout &lt;&lt; v.capacity();</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><strong><span><font face="Times New Roman" size=3>&nbsp;</font></span></strong></p>
<p><span>有趣的是：</span><span>vNew.capacity()</span><span>是</span><span>1000</span><span>，</span><span>而</span><span>v.capacity()</span><span>是</span><span>7</span><span>。</span></p>
<p><span>现在是达到我的目的了，但是并不是很好的解决方法，我们可以像下面这么写：</span></p>
<p>&#160;</p>
<table cellSpacing=0 cellPadding=0 border=0>
    <tbody>
        <tr>
            <td vAlign=top width=528>
            <p><span><span>&nbsp;&nbsp;&nbsp; </span>std::vector&lt;CString&gt;(v).swap(v);</span></p>
            </td>
        </tr>
    </tbody>
</table>
<p><strong><span><font size=3><font face="Times New Roman"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></font></font></span></strong></p>
<p><span>你可以看到我们做了什么？我们创建了一个临时变量代替那个命名的，然后使用</span><span>swap()</span><span><font face="Times New Roman">,</font></span><span>这样我们就去掉了不必要的空间，得到实际大小的</span><span>v</span><span>。</span></p>
<p><strong><span><font face="Times New Roman" size=3>&nbsp;</font></span></strong></p>
<p><font size=3><strong><span>结论</span></strong><strong></strong></font></p>
<p><span>我希望这个文档可以给那些使用</span><span><font face="Times New Roman">STL </font></span><span>vector</span><span>容器的开发者很有价值的参考。我也希望通过阅读这篇文章你可以放心地使用</span><span>vector</span><span>来代替</span><span><font face="Times New Roman">C</font></span><span>语言中的数据了。</span><strong></strong></p>
<p><strong><span><font face="Times New Roman" size=3>&nbsp;</font></span></strong></p>
<p><font size=3><strong><span>参考</span></strong><strong></strong></font></p>
<p><span><font face="Times New Roman">Plauger, P.J. Standard C++ Library Reference. February, 2003. MSDN. </font></span></p>
<p><span><font face="Times New Roman">Schildt, Herbert. C++ from the Ground Up, Second Edition. <st1:city w:st="on"><st1:place w:st="on">Berkeley</st1:place></st1:city>: 1998. </font></span></p>
<p><span><font face="Times New Roman">Sutter, Herb. More Exceptional C++. <st1:city w:st="on"><st1:place w:st="on">Indianapolis</st1:place></st1:city>: 2002. </font></span></p>
</span>
<img src ="http://www.cppblog.com/lovefeel2004/aggbug/118556.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lovefeel2004/" target="_blank">幽梦新影</a> 2010-06-23 13:56 <a href="http://www.cppblog.com/lovefeel2004/archive/2010/06/23/118556.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++ STL编程轻松入门</title><link>http://www.cppblog.com/lovefeel2004/archive/2010/06/02/116947.html</link><dc:creator>幽梦新影</dc:creator><author>幽梦新影</author><pubDate>Tue, 01 Jun 2010 16:17:00 GMT</pubDate><guid>http://www.cppblog.com/lovefeel2004/archive/2010/06/02/116947.html</guid><wfw:comment>http://www.cppblog.com/lovefeel2004/comments/116947.html</wfw:comment><comments>http://www.cppblog.com/lovefeel2004/archive/2010/06/02/116947.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lovefeel2004/comments/commentRss/116947.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lovefeel2004/services/trackbacks/116947.html</trackback:ping><description><![CDATA[<span class=Apple-style-span style="WORD-SPACING: 0px; FONT: medium Simsun; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px"><span class=Apple-style-span style="FONT-SIZE: 14px; LINE-HEIGHT: 21px; FONT-FAMILY: Tahoma, Arial, 宋体">　　作为C++标准不可缺少的一部分，STL应该是渗透在C++程序的角角落落里的。STL不是实验室里的宠儿，也不是程序员桌上的摆设，她的激动人心并非昙花一现。本教程旨在传播和普及STL的基础知识，若能借此机会为STL的推广做些力所能及的事情，到也是件让人愉快的事情。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　1 初识STL：解答一些疑问　　1.1 一个最关心的问题：什么是STL科学领域里所常用的基本数据结构和基本算法。为广大C++程序员们提供了一个可扩展的应用框架，高度体现了<a class=article style="FONT-SIZE: 14px; COLOR: rgb(0,0,255); WORD-BREAK: break-all; LINE-HEIGHT: 19px; TEXT-DECORATION: none" href="http://www.enet.com.cn/esoftware" target=_blank>软件</a>的可复用性。这种现象有些类似于Microsoft Visual C++中的MFC（Microsoft Foundation Class Library），或者是Borland C++ Builder中的VCL(Visual Component Library)，对于此二者，大家一定不会陌生吧。<br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　"什么是STL？"，假如你对STL还知之甚少，那么我想，你一定很想知道这个问题的答案，坦率地讲，要指望用短短数言将这个问题阐述清楚，也决非易事。因此，如果你在看完本节之后还是觉得似懂非懂，大可不必着急，在阅读了后续内容之后，相信你对STL的认识，将会愈加清晰、准确和完整。不过，上述这番话听起来是否有点像是在为自己糟糕的表达能力开脱罪责呢？:）<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　不知道你是否有过这样的经历。在你准备着手完成数据结构老师所布置的家庭作业时，或者在你为你所负责的某个软件项目中添加一项新功能时，你发现需要用到一个链表(List)或者是映射表（Map）之类的东西，但是手头并没有现成的代码。于是在你开始正式考虑程序功能之前，手工实现List或者Map是不可避免的。于是&#8230;&#8230;，最终你顺利完成了任务。或许此时，作为一个具有较高素养的程序员的你还不肯罢休（或者是一个喜欢偷懒的优等生:），因为你会想到，如果以后还遇到这样的情况怎么办？没有必要再做一遍同样的事情吧！<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　如果说上述这种情形每天都在发生，或许有点夸张。但是，如果说整个软件领域里，数十年来确实都在为了一个目标而奋斗--可复用性（reusability），这看起来似乎并不夸张。从最早的面向过程的函数库，到面向对象的<a style="FONT-SIZE: 12px; COLOR: rgb(78,78,78); WORD-BREAK: break-all; TEXT-DECORATION: none" href="http://www.sxs.la/">程序设计</a>思想，到各种组件技术（如：COM、EJB），到设计模式（design pattern）等等。而STL也在做着类似的事情，同时在它背后蕴涵着一种新的程序设计思想--泛型化设计（generic programming）。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　继续上面提到的那个例子，假如你把List或者map完好的保留了下来，正在暗自得意。且慢，如果下一回的List里放的不是浮点数而是整数呢？如果你所实现的Map在效率上总是令你不太满意并且有时还会出些bug呢？你该如何面对这些问题？使用STL是一个不错的选择，确实如此，STL可以漂亮地解决上面提到的这些问题，尽管你还可以寻求其他方法。<br><br><span class=Apple-style-span style="WORD-SPACING: 0px; FONT: medium Simsun; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px"><span class=Apple-style-span style="FONT-SIZE: 14px; LINE-HEIGHT: 21px; FONT-FAMILY: Tahoma, Arial, 宋体">　说了半天，到底STL是什么东西呢？<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　STL（Standard Template Library），即标准模板库，是一个具有工业强度的，高效的C++程序库。它被容纳于C++标准程序库（C++ Standard Library）中，是ANSI/ISO C++标准中最新的也是极具革命性的一部分。该库包含了诸多在<a class=article style="FONT-SIZE: 14px; COLOR: rgb(0,0,255); WORD-BREAK: break-all; LINE-HEIGHT: 19px; TEXT-DECORATION: none" href="http://product.enet.com.cn/price/plist3.shtml" target=_blank>计算机</a><span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　从逻辑层次来看，在STL中体现了泛型化程序设计的思想（generic programming），引入了诸多新的名词，比如像需求（requirements），概念（concept），模型（model），容器（container），算法（algorithmn），迭代子（iterator）等。与OOP（object-oriented programming）中的多态（polymorphism）一样，泛型也是一种<a class=article style="FONT-SIZE: 14px; COLOR: rgb(0,0,255); WORD-BREAK: break-all; LINE-HEIGHT: 19px; TEXT-DECORATION: none" href="http://www.enet.com.cn/esoftware" target=_blank>软件</a>的复用技术。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　从实现层次看，整个STL是以一种类型参数化（type parameterized）的方式实现的，这种方式基于一个在早先C++标准中没有出现的语言特性--模板（template）。如果查阅任何一个版本的STL源代码，你就会发现，模板作为构成整个STL的基石是一件千真万确的事情。除此之外，还有许多C++的新特性为STL的实现提供了方便。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　不知你对这里一下子冒出这么多术语做何感想，希望不会另你不愉快。假如你对它们之中的大多数不甚了解，敬请放心，在后续内容中将会对这些名词逐一论述。正如开头所提到的。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　有趣的是，对于STL还有另外一种解释--STepanov &amp; Lee，前者是指Alexander Stepanov，STL的创始人；而后者是Meng Lee，她也是使STL得以推行的功臣，第一个STL成品就是他们合作完成的。这一提法源自1995年3月，Dr.Dobb's Journal特约记者, 著名技术书籍作家Al Stevens对Alexander Stepanov的一篇专访。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　1.2 追根溯源：STL的历史学院教授David Musser共同开发了一种叫做Tecton的语言。尽管这次尝试最终没有取得实用性的成果，但却给了Stepanov很大的启示。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　在结识新朋友的时候，大多数人总是忍不住想了解对方的过去。本节将带您简单回顾一下STL的过去。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　被誉为STL之父的Alexander Stepanov，出生于苏联莫斯科，早在20世纪70年代后半期，他便已经开始考虑，在保证效率的前提下，将算法从诸多具体应用之中抽象出来的可能性，这便是后来泛型化思想的雏形。为了验证自己的思想，他和纽约州立大学教授Deepak Kapur，伦塞里尔技术<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　在随后的几年中，他又和David Musser等人先后用Schema<a style="FONT-SIZE: 12px; COLOR: rgb(78,78,78); WORD-BREAK: break-all; TEXT-DECORATION: none" href="http://www.sxs.la/">语言</a>（一种Lisp语言的变种）和Ada语言建立了一些大型程序库。这其间，Alexander Stepanov开始意识到，在当时的面向对象程序设计思想中所存在的一些问题，比如抽象数据类型概念所存在的缺陷。Stepanov希望通过对软件领域中各组成部分的分类，逐渐形成一种软件设计的概念性框架。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　1987年左右，在贝尔实验室工作的Alexander Stepanov开始首次采用C++语言进行泛型软件库的研究。但遗憾的是，当时的C++语言还没有引入模板（template）的语法，现在我们可以清楚的看到，模板概念之于STL实现，是何等重要。是时使然，采用继承机制是别无选择的。尽管如此，Stepanov还是开发出了一个庞大的算法库。与此同时，在与Andrew Koenig（前ISO C++标准化委员会主席）和Bjarne Stroustrup（C++语言的创始人）等顶级大师们的共事过程中，Stepanov开始注意到C/C++语言在实现其泛型思想方面所具有的潜在优势。就拿C/C++中的指针而言，它的灵活与高效运用，使后来的STL在实现泛型化的同时更是保持了高效率。另外，在STL中占据极其重要地位的迭代子概念便是源自于C/C++中原生指针（ native pointer）的抽象。<br><br><span class=Apple-style-span style="WORD-SPACING: 0px; FONT: medium Simsun; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px"><span class=Apple-style-span style="FONT-SIZE: 14px; LINE-HEIGHT: 21px; FONT-FAMILY: Tahoma, Arial, 宋体">　　1988年，Alexander Stepanov开始进入<a class=article style="FONT-SIZE: 14px; COLOR: rgb(0,0,255); WORD-BREAK: break-all; LINE-HEIGHT: 19px; TEXT-DECORATION: none" href="http://product.enet.com.cn/price/plist3_2283.shtml" target=_blank>惠普</a>的Palo Alto实验室工作，在随后的4年中，他从事的是有关<a class=article style="FONT-SIZE: 14px; COLOR: rgb(0,0,255); WORD-BREAK: break-all; LINE-HEIGHT: 19px; TEXT-DECORATION: none" href="http://product.enet.com.cn/price/plist56.shtml" target=_blank>磁盘</a>驱动器方面的工作。直到1992年，由于参加并主持了实验室主任Bill Worley所建立的一个有关算法的研究项目，才使他重新回到了泛型化算法的研究工作上来。项目自建立之后，参与者从最初的8人逐渐减少，最后只剩下两个人--Stepanove本人和Meng Lee。经过长时间的努力，最终，信念与汗水所换来的是一个包含有大量数据结构和算法部件的庞大运行库。这便是现在的STL的雏形（同时也是STL的一个实现版本--HP STL）。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　1993年，当时在贝尔实验室的Andrew Koenig看到了Stepanove的研究成果，很是兴奋。在他的鼓励与帮助下，Stepanove于是年9月的圣何塞为ANSI/ISO C++标准委员会做了一个相关演讲（题为"The Science of C++ Programming"），向委员们讲述了其观念。然后又于次年3月，在圣迭戈会议上，向委员会提交了一份建议书，以期使STL成为C++标准库的一部分。尽管这一建议十分庞大，以至于降低了被通过的可能性，但由于其所包含的新思想，投票结果以压倒多数的意见认为推迟对该建议的决定。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　随后，在众人的帮助之下，包括Bjarne Stroustrup在内，Stepanove又对STL进行了改进。同时加入了一个封装内存模式信息的抽象模块，也就是现在STL中的allocator，它使STL的大部分实现都可以独立于具体的内存模式，从而独立于具体平台。在同年夏季的滑铁卢会议上，委员们以80%赞成，20%反对，最终通过了提案，决定将STL正式纳入C++标准化进程之中，随后STL便被放进了会议的工作文件中。自此，STL终于成为了C++家族中的重要一员。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　此后，随着C++标准的不断改进，STL也在不断地作着相应的演化。直至1998年，ANSI/ISO C++标准正式定案，STL始终是C++标准中不可或缺的一大部件。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　1.3 千丝万缕的联系　　1.3.1 STL和C++　　1.3.2 STL和C++标准函数库1.3.3 STL和GP，GP和OOP 　　1.4 STL的不同实现版本　　1.4.1 HP STL　　1.4.2 P.J. Plauger STLhttp://www.dinkumware.comVisualStudiohashset容器。1.4.3 Rouge Wave STLhttp://www.rougewave.com源代码C:Program Files\Borland\Cbuilder6\Include\oldstl）。1.4.4 STLporthttp://www.stlport.org免费下载VC中的STL要快。比Rouge Wave STL更符合标准，也更容易移植。Borland C++ Builder已经在其6.0版中加入了对STLport的支持，它使用的STLport就是4.5版的，C++ Builder 6.0同时还提供了STLport的使用说明。你可以在C++ Builder的Include\Stlport子目录下找到所有头文件（比如：C:\Program Files\Borland\Cbuilder6\Include\Stlport）。1.4.5 SGI STLhttp://www.sgi.com新版本是3.3。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　在你了解了STL的过去之后，一些名词开始不断在你的大脑中浮现，STL、C++、C++标准函数库、泛型程序设计、面向对象程序设计&#8230;&#8230;，这些概念意味着什么？他们之间的关系又是什么？如果你想了解某些细节，这里也许有你希望得到的答案。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　没有C++语言就没有STL，这么说毫不为过。一般而言，STL作为一个泛型化的数据结构和<a style="FONT-SIZE: 12px; COLOR: rgb(78,78,78); WORD-BREAK: break-all; TEXT-DECORATION: none" href="http://www.sxs.la/">算法</a>库，并不牵涉具体语言（当然，在C++里，它被称为STL）。也就是说，如果条件允许，用其他语言也可以实现之。这里所说的条件，主要是指类似于"模板"这样的语法机制。如果你没有略过前一节内容的话，应该可以看到，Alexander Stepanov在选择C++语言作为实现工具之前，早以采用过多种程序设计语言。但是，为什么最终还是C++幸运的承担了这个历史性任务呢？原因不仅在于前述那个条件，还在于C++在某些方面所表现出来的优越特性，比如：高效而灵活的指针。但是如果把C++作为一种OOP（Object-Oriented Programming，面向对象程序设计）语言来看待的话（事实上我们一般都是这么认为的，不是吗？），其功能强大的继承机制却没有给STL的实现帮上多大的忙。在STL的源代码里，并没有太多太复杂的继承关系。继承的思想，甚而面向对象的思想，还不足以实现类似STL这样的泛型库。C++只有在引入了"模板"之后，才直接导致了STL的诞生。这也正是为什么，用其他比C++更纯的面向对象语言无法实现泛型思想的一个重要原因。当然，事情总是在变化之中，像Java在这方面，就是一个很好的例子，jdk1.4中已经加入了泛型的特性。<br><br><span class=Apple-style-span style="WORD-SPACING: 0px; FONT: medium Simsun; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px"><span class=Apple-style-span style="FONT-SIZE: 14px; LINE-HEIGHT: 21px; FONT-FAMILY: Tahoma, Arial, 宋体">　　此外，STL对于C++的发展，尤其是模板机制，也起到了促进作用。比如：模板函数的偏特化（template function partial specialization），它被用于在特定应用场合，为一般模板函数提供一系列特殊化版本。这一特性是继STL被ANSI/ISO C++标准委员会通过之后，在Bjarne和Stepanov共同商讨之下并由Bjarne向委员会提出建议的，最终该项建议被通过。这使得STL中的一些算法在处理特殊情形时可以选择非一般化的方式，从而保证了执行的效率。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　STL是最新的C++标准函数库中的一个子集，这个庞大的子集占据了整个库的大约80%的分量。而作为在实现STL过程中扮演关键角色的模板则充斥了几乎整个C++标准函数库。在这里，我们有必要看一看C++标准函数库里包含了哪些内容，其中又有哪些是属于标准模板库（即STL）的。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　C++标准函数库为C++程序员们提供了一个可扩展的基础性框架。我们从中可以获得极大的便利，同时也可以通过继承现有类，自己编制符合接口规范的容器、算法、迭代子等方式对之进行扩展。它大致包含了如下几个组件：<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　C标准函数库，基本保持了与原有C语言程序库的良好兼容，尽管有些微变化。人们总会忍不住留恋过去的美好岁月，如果你曾经是一个C程序员，对这一点一定体会颇深。或许有一点会让你觉得奇怪，那就是在C++标准库中存在两套C的函数库，一套是带有.h扩展名的（比如<stdio.h style="WORD-BREAK: break-all">），而另一套则没有（比如<cstdio style="WORD-BREAK: break-all">）。它们确实没有太大的不同。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　语言支持（language support）部分，包含了一些标准类型的定义以及其他特性的定义，这些内容，被用于标准库的其他地方或是具体的应用程序中。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　诊断（diagnostics）部分，提供了用于程序诊断和报错的功能，包含了异常处理（exception handling），断言（assertions），错误代码（error number codes）三种方式。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　通用工具（general utilities）部分，这部分内容为C++标准库的其他部分提供支持，当然你也可以在自己的程序中调用相应功能。比如：动态内存管理工具，日期/时间处理工具。记住，这里的内容也已经被泛化了（即采用了模板机制）。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　字符串（string）部分，用来代表和处理文本。它提供了足够丰富的功能。事实上，文本是一个string对象，它可以被看作是一个字符序列，字符类型可能是char，或者wchar_t等等。string可以被转换成char*类型，这样便可以和以前所写的C/C++<a style="FONT-SIZE: 12px; COLOR: rgb(78,78,78); WORD-BREAK: break-all; TEXT-DECORATION: none" href="http://www.sxs.la/">代码</a>和平共处了。因为那时侯除了char*，没有别的。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　国际化（internationalization）部分，作为OOP特性之一的封装机制在这里扮演着消除文化和地域差异的角色，采用locale和facet可以为程序提供众多国际化支持，包括对各种字符集的支持，日期和时间的表示，数值和货币的处理等等。毕竟，在中国和在美国，人们表示日期的习惯是不同的。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　容器（containers）部分，STL的一个重要组成部分，涵盖了许多数据结构，比如前面曾经提到的链表，还有：vector（类似于大小可动态增加的数组）、queue（队列）、stack（堆栈）&#8230;&#8230;。string也可以看作是一个容器，适用于容器的方法同样也适用于string。现在你可以轻松的完成数据结构课程的家庭作业了。<br><br><span class=Apple-style-span style="WORD-SPACING: 0px; FONT: medium Simsun; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px"><span class=Apple-style-span style="FONT-SIZE: 14px; LINE-HEIGHT: 21px; FONT-FAMILY: Tahoma, Arial, 宋体">　　算法（algorithms）部分，STL的一个重要组成部分，包含了大约70个通用算法，用于操控各种容器，同时也可以操控内建数组。比如：find用于在容器中查找等于某个特定值的元素，for_each用于将某个函数应用到容器中的各个元素上，sort用于对容器中的元素排序。所有这些操作都是在保证执行效率的前提下进行的，所以，如果在你使用了这些算法之后程序变得效率底下，首先一定不要怀疑这些算法本身，仔细检查一下程序的其他地方。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　迭代器（iterators）部分，STL的一个重要组成部分，如果没有迭代器的撮合，容器和算法便无法结合的如此完美。事实上，每个容器都有自己的迭代器，只有容器自己才知道如何访问自己的元素。它有点像指针，算法通过迭代器来定位和操控容器中的元素。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　数值（numerics）部分，包含了一些数学运算功能，提供了复数运算的支持。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　输入/输出（input/output）部分，就是经过模板化了的原有标准库中的iostream部分，它提供了对C++程序输入输出的基本支持。在功能上保持了与原有iostream的兼容，并且增加了异常处理的机制，并支持国际化（internationalization）。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　总体上，在<a style="FONT-SIZE: 12px; COLOR: rgb(78,78,78); WORD-BREAK: break-all; TEXT-DECORATION: none" href="http://www.sxs.la/html/DevLanguage/Cpp/">C++</a>标准函数库中，STL主要包含了容器、算法、迭代器。string也可以算做是STL的一部分。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　正如前面所提到的，在STL的背后蕴含着泛型化程序设计（GP）的思想，在这种思想里，大部分基本算法被抽象，被泛化，独立于与之对应的数据结构，用于以相同或相近的方式处理各种不同情形。这一思想和面向对象的程序设计思想（OOP）不尽相同，因为，在OOP中更注重的是对数据的抽象，即所谓抽象数据类型（Abstract Data Type），而算法则通常被附属于数据类型之中。几乎所有的事情都可以被看作类或者对象（即类的实例），通常，我们所看到的算法被作为成员函数（member function）包含在类（class）中，类和类则构成了错综复杂的继承体系。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　尽管在象C++这样的程序设计语言中，你还可以用全局函数来表示算法，但是在类似于Java这样的纯面向对象的语言中，全局函数已经被"勒令禁止"了。因此，用Java来模拟GP思想是颇为困难的。如果你对前述的STL历史还有印象的话，应该记得Alexander Stepanove也曾用基于OOP的语言尝试过实现GP思想，但是效果并不好，包括没有引入模板之前的C++语言。站在巨人的肩膀上，我们可以得出这样的结论，在OOP中所体现的思想与GP的思想确实是相异的。C++并不是一种纯面向对象的程序设计语言，它的绝妙之处，就在于既满足了OOP，又成全了GP。对于后者，模板立下了汗马功劳。另外，需要指出的是，尽管GP和OOP有诸多不同，但这种不同还不至于到"水火不容"的地步。并且，在实际运用的时候，两者的结合使用往往可以使问题的解决更为有效。作为GP思想实例的STL本身便是一个很好的范例，如果没有继承，不知道STL会是什么样子，似乎没有人做过这样的试验。<br><span class=Apple-style-span style="WORD-SPACING: 0px; FONT: medium Simsun; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px"><span class=Apple-style-span style="FONT-SIZE: 14px; LINE-HEIGHT: 21px; FONT-FAMILY: Tahoma, Arial, 宋体">　　相信你对STL的感性认识应该有所提高了，是该做一些实际的工作了，那么我们首先来了解一下STL的不同实现版本。ANSI/ISO C++文件中的STL是一个仅被描述在纸上的标准，对于诸多C++编译器而言，需要有各自实际的STL，它们或多或少的实现了标准中所描述的内容，这样才能够为我们所用。之所以有不同的实现版本，则存在诸多原因，有历史的原因，也有各自编译器生产厂商的原因。以下是几个常见的STL实现版本。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　HP STL是所有其它STL实现版本的根源。它是STL之父Alexander Stepanov在<a class=article style="FONT-SIZE: 14px; COLOR: rgb(0,0,255); WORD-BREAK: break-all; LINE-HEIGHT: 19px; TEXT-DECORATION: none" href="http://product.enet.com.cn/price/plist4_2283.shtml" target=_blank>惠普</a>的Palo Alto实验室工作时，和Meng Lee共同完成的，是第一个STL的实现版本（参见1.2节）。这个STL是开放源码的，所以它允许任何人免费使用、复制、修改、发布和销售该<a class=article style="FONT-SIZE: 14px; COLOR: rgb(0,0,255); WORD-BREAK: break-all; LINE-HEIGHT: 19px; TEXT-DECORATION: none" href="http://www.enet.com.cn/esoftware" target=_blank>软件</a>和相关文档，前提是必须在所有相关文件中加入HP STL的版本信息和授权信息。现在已经很少直接使用这个版本的STL了。<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　P. J. Plauger STL属于个人作品，由P. J. Plauger本人实现，是HP STL的一个继承版本，因此在其所有头文件中都含有HP STL的相关声明，同时还有P. J. Plauger本人的版权声明。P. J. Plauger是标准C中stdio库的早期实现者，现在是C/C++ User's Journal的主编，与Microsoft保持着良好的关系。P. J. Plauger STL便是被用于Microsoft的Visual C++中的。在Windows平台下的同类版本中，其性能不错，但是queue组件（队列，一种容器）的效率不理想，同时由于Visual C++对C++语言标准的支持不是很好（至少直到VC6.0为止，还是如此），因此一定程度上影响了P. J. Plauger STL的性能。此外，该版本的源代码可读性较差，你可以在VC的Include子目录下找到所有源文件（比如：C:\Program Files\Microsoft Visual Studio\VC98\Include）。因为不是开放源码的（open source），所以这些<a style="FONT-SIZE: 12px; COLOR: rgb(78,78,78); WORD-BREAK: break-all; TEXT-DECORATION: none" href="http://www.sxs.la/">源代码</a>是不能修改和销售的，目前P.J. Plauger STL由Dinkumware公司提供相关服务.<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　Rouge Wave STL是由Rouge Wave公司实现的，也是HP STL的一个继承版本，除了HP STL的相关声明之外，还有Rouge Wave公司的版权声明。同时，它也不是开放源码的，因此无法修改和销售。该版本被Borland C++ Builder所采用，你可以在C++ Builder的Include子目录下找到所有头文件（比如：C:\Program Files\Borland\Cbuilder5\Include）。尽管Rouge Wave STL的性能不是很好，但由于C++ Builder对C++语言标准的支持还算不错，使其表现在一定程度上得以改善。此外，其源代码的可读性较好。可以从如下网站得到更详细的情况介绍：<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　STLport最初源于俄国人Boris Fomitchev的一个开发项目，主要用于将SGI STL的基本代码移植到其他诸如C++Builder或者是Visual C++这样的主流编译器上。因为SGI STL属于开放源码，所以STLport才有权这样做。目前STLport的最新版本是4.5。可以从如下网站得到更详细的情况介绍：<span class=Apple-converted-space>&nbsp;</span><br style="WORD-BREAK: break-all"><br style="WORD-BREAK: break-all">　　SGI STL是由Silicon Graphics Computer System, Inc公司实现的，其设计者和编写者包括Alexander Stepanov和Matt Austern，同样它也是HP STL的一个继承版本。它属于开放源码，因此你可以修改和销售它。SGI STL被GCC（linux下的C++编译器）所采用，你可以在GCC的Include子目录下找到所有头文件（比如：C:\cygnus\cygwin-b20\include\g++\include）。由于GCC对C++语言标准的支持很好，SGI STL在linux平台上的性能相当出色。此外，其源代码的可读性也很好。</span></span></span></span><br></cstdio></stdio.h></span></span></span></span><br><br></span></span></span></span>
<img src ="http://www.cppblog.com/lovefeel2004/aggbug/116947.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lovefeel2004/" target="_blank">幽梦新影</a> 2010-06-02 00:17 <a href="http://www.cppblog.com/lovefeel2004/archive/2010/06/02/116947.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>C++类库：OTL通用的数据库连接类库</title><link>http://www.cppblog.com/lovefeel2004/archive/2010/06/02/116946.html</link><dc:creator>幽梦新影</dc:creator><author>幽梦新影</author><pubDate>Tue, 01 Jun 2010 16:05:00 GMT</pubDate><guid>http://www.cppblog.com/lovefeel2004/archive/2010/06/02/116946.html</guid><wfw:comment>http://www.cppblog.com/lovefeel2004/comments/116946.html</wfw:comment><comments>http://www.cppblog.com/lovefeel2004/archive/2010/06/02/116946.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lovefeel2004/comments/commentRss/116946.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lovefeel2004/services/trackbacks/116946.html</trackback:ping><description><![CDATA[<span class=Apple-style-span style="WORD-SPACING: 0px; FONT: medium Simsun; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px"><span class=Apple-style-span style="FONT-SIZE: 14px; COLOR: rgb(50,62,50); LINE-HEIGHT: 21px; FONT-FAMILY: simsun, 宋体, sans-serif; TEXT-ALIGN: left">
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal">OTL是一个纯C++的通用数据库连接模板库，可以支持各种当下流行的数据库，如Oracle，Sybase, MySQL, PostgreSQL, EnterpriseDB, SQLite,&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>MS ACCESS, Firebird等等.它是一个跨平台类库，在MS Windows, Linux/Unix/Mac OS X 都可以使用。</p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal">下载网址：<font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" size=2><span lang=EN-US style="WORD-BREAK: normal; LINE-HEIGHT: 19px; FONT-FAMILY: Arial; WORD-WRAP: normal" xml:lang="EN-US"><a style="COLOR: rgb(1,59,135); TEXT-DECORATION: none" href="http://otl.sourceforge.net/" target=_blank><font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" color=#336699>http://otl.sourceforge.net/</font></a></span></font></p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal"><font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" size=2><span lang=EN-US style="WORD-BREAK: normal; LINE-HEIGHT: 19px; FONT-FAMILY: Arial; WORD-WRAP: normal" xml:lang="EN-US">OTL使用简单, 只要头文件中包含有: #include "<font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" size=2>otlv4.h</font>" 就可，实际上整个OTL就一个.H的文件，使用起来极为的方便。</span></font></p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal">OTL使用方法：</p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal">1、首先指定要连接的数据库类型，OTL用<font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" size=2>宏定义</font>来指定要连接的数据库类型。<font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" size=2><font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" face=Arial>OTL</font><span style="WORD-BREAK: normal; LINE-HEIGHT: 19px; FONT-FAMILY: 宋体; WORD-WRAP: normal">会根据这个宏定义来初始化数据库连接的环境。</span></font></p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal">相关的宏定义列表<span class=Apple-converted-space>&nbsp;</span><a style="COLOR: rgb(1,59,135); TEXT-DECORATION: none" href="http://otl.sourceforge.net/otl3_compile.htm">http://otl.sourceforge.net/otl3_compile.htm</a></p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal">如： #define OTL_ORA8I 表示连接Oracle 8i 数据库。</p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal">&nbsp;<wbr></p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal"><font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" size=2><span lang=EN-US style="WORD-BREAK: normal; LINE-HEIGHT: 19px; FONT-FAMILY: Arial; WORD-WRAP: normal" xml:lang="EN-US">2、例子</span></font></p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal"><font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" size=2><span lang=EN-US style="WORD-BREAK: normal; LINE-HEIGHT: 19px; FONT-FAMILY: Arial; WORD-WRAP: normal" xml:lang="EN-US">#include &lt;iostream&gt;<br>using namespace std;<br>#include &lt;stdio.h&gt;</span></font></p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal"><font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" size=2><span lang=EN-US style="WORD-BREAK: normal; LINE-HEIGHT: 19px; FONT-FAMILY: Arial; WORD-WRAP: normal" xml:lang="EN-US">#define OTL_ORA8I // 指定连接的数据库类型<br>#include &lt;otlv4.h&gt; // include the OTL 4 header file</span></font></p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal"><font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" size=2><span lang=EN-US style="WORD-BREAK: normal; LINE-HEIGHT: 19px; FONT-FAMILY: Arial; WORD-WRAP: normal" xml:lang="EN-US">otl_connect db; // 定义数据库实例</span></font></p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal">&nbsp;<wbr></p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal"><font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" size=2><span lang=EN-US style="WORD-BREAK: normal; LINE-HEIGHT: 19px; FONT-FAMILY: Arial; WORD-WRAP: normal" xml:lang="EN-US">void insert()<br>// 添加记录</span></font></p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal"><font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" size=2><span lang=EN-US style="WORD-BREAK: normal; LINE-HEIGHT: 19px; FONT-FAMILY: Arial; WORD-WRAP: normal" xml:lang="EN-US">{<br>&nbsp;<wbr>otl_stream o(50, // buffer size<br>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>"insert into test_tab values(:f1&lt;float&gt;,:f2&lt;char[31]&gt;)",<br>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>// SQL statement<br>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>db // connect object<br>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>);<br>&nbsp;<wbr>char tmp[32];</span></font></p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal"><font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" size=2><span lang=EN-US style="WORD-BREAK: normal; LINE-HEIGHT: 19px; FONT-FAMILY: Arial; WORD-WRAP: normal" xml:lang="EN-US">&nbsp;<wbr>for(int i=1;i&lt;=100;++i){<br>#if defined(_MSC_VER)<br>#if (_MSC_VER &gt;= 1400) // VC++ 8.0 or higher<br>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>sprintf_s(tmp,sizeof(tmp),"Name%d",i);<br>#else<br>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>sprintf(tmp,"Name%d",i);<br>#endif<br>#else<br>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>sprintf(tmp,"Name%d",i);<br>#endif<br>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>o&lt;&lt;static_cast&lt;float&gt;(i)&lt;&lt;tmp;<br>&nbsp;<wbr>}<br>}</span></font></p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal"><font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" size=2><span lang=EN-US style="WORD-BREAK: normal; LINE-HEIGHT: 19px; FONT-FAMILY: Arial; WORD-WRAP: normal" xml:lang="EN-US">//查询记录</span></font></p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal"><font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" size=2><span lang=EN-US style="WORD-BREAK: normal; LINE-HEIGHT: 19px; FONT-FAMILY: Arial; WORD-WRAP: normal" xml:lang="EN-US">void select()<br>{<br>&nbsp;<wbr>otl_stream i(50, // buffer size<br>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>"begin "<br>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>"&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>open :cur1 for "<br>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>"&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>select * from test_tab "<br>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>"&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>where f1&gt;=:f&lt;int&gt; and f1&lt;=:f*2; "<br>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>"end;", // SELECT statement via referenced cursor<br>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>db, // connect object<br>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>":cur1" // referenced cursor placeholder name<br>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>);<br>&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>// create select stream<br>&nbsp;<wbr><br>&nbsp;<wbr>otl_column_desc* desc;<br>&nbsp;<wbr>int desc_len;</span></font></p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal"><font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" size=2><span lang=EN-US style="WORD-BREAK: normal; LINE-HEIGHT: 19px; FONT-FAMILY: Arial; WORD-WRAP: normal" xml:lang="EN-US">&nbsp;<wbr>i&lt;&lt;4; // Before the child SELECT statement can be described,<br>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>// the PL/SQL master block needs to be executed.<br>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>// Forcing the execution of the blcok by entering its input<br>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>// patameter.</span></font></p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal"><font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" size=2><span lang=EN-US style="WORD-BREAK: normal; LINE-HEIGHT: 19px; FONT-FAMILY: Arial; WORD-WRAP: normal" xml:lang="EN-US">&nbsp;<wbr>desc=i.describe_select(desc_len);</span></font></p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal"><font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" size=2><span lang=EN-US style="WORD-BREAK: normal; LINE-HEIGHT: 19px; FONT-FAMILY: Arial; WORD-WRAP: normal" xml:lang="EN-US">&nbsp;<wbr>for(int n=0;n&lt;desc_len;++n){<br>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>cout&lt;&lt;"========== COLUMN #"&lt;&lt;n+1&lt;&lt;" ==========="&lt;&lt;endl;<br>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>cout&lt;&lt;"name="&lt;&lt;desc[n].name&lt;&lt;endl;<br>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>cout&lt;&lt;"dbtype="&lt;&lt;desc[n].dbtype&lt;&lt;endl;<br>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>cout&lt;&lt;"otl_var_dbtype="&lt;&lt;desc[n].otl_var_dbtype&lt;&lt;endl;<br>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>cout&lt;&lt;"dbsize="&lt;&lt;desc[n].dbsize&lt;&lt;endl;<br>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>cout&lt;&lt;"scale="&lt;&lt;desc[n].scale&lt;&lt;endl;<br>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>cout&lt;&lt;"prec="&lt;&lt;desc[n].prec&lt;&lt;endl;<br>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>cout&lt;&lt;"nullok="&lt;&lt;desc[n].nullok&lt;&lt;endl;<br>&nbsp;<wbr>}<br>&nbsp;<wbr></span></font></p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal"><font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" size=2><span lang=EN-US style="WORD-BREAK: normal; LINE-HEIGHT: 19px; FONT-FAMILY: Arial; WORD-WRAP: normal" xml:lang="EN-US">}</span></font></p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal"><font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" size=2><span lang=EN-US style="WORD-BREAK: normal; LINE-HEIGHT: 19px; FONT-FAMILY: Arial; WORD-WRAP: normal" xml:lang="EN-US">int main()<br>{<br>&nbsp;<wbr>otl_connect::otl_initialize(); //&nbsp;<wbr>初始化Oracle环境<br>&nbsp;<wbr>try{</span></font></p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal"><font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" size=2><span lang=EN-US style="WORD-BREAK: normal; LINE-HEIGHT: 19px; FONT-FAMILY: Arial; WORD-WRAP: normal" xml:lang="EN-US">&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>db.rlogon("scott/tiger"); // 连接Oracle</span></font></p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal"><font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" size=2><span lang=EN-US style="WORD-BREAK: normal; LINE-HEIGHT: 19px; FONT-FAMILY: Arial; WORD-WRAP: normal" xml:lang="EN-US">&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>otl_cursor::direct_exec<br>&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>(<br>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>db,<br>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>"drop table test_tab",<br>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>otl_exception::disabled // disable OTL exceptions<br>&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>); // drop table</span></font></p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal"><font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" size=2><span lang=EN-US style="WORD-BREAK: normal; LINE-HEIGHT: 19px; FONT-FAMILY: Arial; WORD-WRAP: normal" xml:lang="EN-US">&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>otl_cursor::direct_exec<br>&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>(<br>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>db,<br>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>"create table test_tab(f1 number, f2 varchar2(30))"<br>&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>);&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>// create table</span></font></p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal"><font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" size=2><span lang=EN-US style="WORD-BREAK: normal; LINE-HEIGHT: 19px; FONT-FAMILY: Arial; WORD-WRAP: normal" xml:lang="EN-US">&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>insert();&nbsp;<wbr><br>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>select();</span></font></p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal"><font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" size=2><span lang=EN-US style="WORD-BREAK: normal; LINE-HEIGHT: 19px; FONT-FAMILY: Arial; WORD-WRAP: normal" xml:lang="EN-US">&nbsp;<wbr>}</span></font></p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal"><font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" size=2><span lang=EN-US style="WORD-BREAK: normal; LINE-HEIGHT: 19px; FONT-FAMILY: Arial; WORD-WRAP: normal" xml:lang="EN-US">&nbsp;<wbr>catch(otl_exception&amp; p){ // intercept OTL exceptions<br>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>cerr&lt;&lt;p.msg&lt;&lt;endl; // print out error message<br>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>cerr&lt;&lt;p.stm_text&lt;&lt;endl; // print out SQL that caused the error<br>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>cerr&lt;&lt;p.var_info&lt;&lt;endl; // print out the variable that caused the error<br>&nbsp;<wbr>}</span></font></p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal"><font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" size=2><span lang=EN-US style="WORD-BREAK: normal; LINE-HEIGHT: 19px; FONT-FAMILY: Arial; WORD-WRAP: normal" xml:lang="EN-US">&nbsp;<wbr>db.logoff(); //断开数据库连接</span></font></p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal"><font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" size=2><span lang=EN-US style="WORD-BREAK: normal; LINE-HEIGHT: 19px; FONT-FAMILY: Arial; WORD-WRAP: normal" xml:lang="EN-US">&nbsp;<wbr>return 0;</span></font></p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal"><font style="WORD-BREAK: normal; LINE-HEIGHT: 19px; WORD-WRAP: normal" size=2><span lang=EN-US style="WORD-BREAK: normal; LINE-HEIGHT: 19px; FONT-FAMILY: Arial; WORD-WRAP: normal" xml:lang="EN-US">}</span></font></p>
</span></span>
<img src ="http://www.cppblog.com/lovefeel2004/aggbug/116946.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lovefeel2004/" target="_blank">幽梦新影</a> 2010-06-02 00:05 <a href="http://www.cppblog.com/lovefeel2004/archive/2010/06/02/116946.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>boost库linux编译安装</title><link>http://www.cppblog.com/lovefeel2004/archive/2010/06/01/116943.html</link><dc:creator>幽梦新影</dc:creator><author>幽梦新影</author><pubDate>Tue, 01 Jun 2010 15:36:00 GMT</pubDate><guid>http://www.cppblog.com/lovefeel2004/archive/2010/06/01/116943.html</guid><wfw:comment>http://www.cppblog.com/lovefeel2004/comments/116943.html</wfw:comment><comments>http://www.cppblog.com/lovefeel2004/archive/2010/06/01/116943.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lovefeel2004/comments/commentRss/116943.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lovefeel2004/services/trackbacks/116943.html</trackback:ping><description><![CDATA[<span class=Apple-style-span style="WORD-SPACING: 0px; FONT: medium Simsun; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px"><span class=Apple-style-span style="FONT-SIZE: 14px; COLOR: rgb(50,62,50); LINE-HEIGHT: 21px; FONT-FAMILY: simsun, 宋体, sans-serif; TEXT-ALIGN: left">&nbsp;<wbr>&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>相对于Windows来，Linux下的boost编译简单至极。没有那么多的可选编译器，没有那长的编译时间，没有那么多的硬盘使用量，统一的inlude和lib目录，你熟悉命令行，不使用IDE，不需要我那么罗嗦的介绍怎么配置EditPlus。<br><br>首先是下载boost，可以在此
<pre style="WHITE-SPACE: normal">http://sourceforge.net/projects/boost</pre>
寻找一个合适的版本。比如我下载的是boost_1_33_1.tar.gz，解压到/opt。<br><br>
<pre style="WHITE-SPACE: normal">tar xzvf boost_1_33_1.tar.gz -C/opt</pre>
<br>提醒：做这些事情的时候你需要有root权限。<br><br>进入boost目录：<br><br>
<pre style="WHITE-SPACE: normal">cd /opt/boost_1_33_1</pre>
<br>首先我们要编译bjam：<br><br>
<pre style="WHITE-SPACE: normal">cd tools/build/jam_src/<br>./build.sh<br></pre>
<br>很快编译结束，默认情况下，bjam会被复制到/usr/local/bin/bjam。<br><br>现在你可以使用bjam编译boost了。<br><br>
<pre style="WHITE-SPACE: normal">cd ../../..<br>bjam -sTOOLS=gcc install<br></pre>
<br>编译时间不会如windows那么长久，在我的电脑上编译了大约40分钟。你可以在前后使用df命令检查下磁盘使用，在我的电脑上，编译boost花费了500M的空间。<br><br>使用install会把头文件复制到/usr/local/include/boost-1_33_1中，把生成的lib复制到/usr/local/lib中。这些完成之后，记得要使用ldconfig来更新动态链接库。<br><br>在测试两个例子之前，我们先设置几个环境变量。<br><br>
<pre style="WHITE-SPACE: normal">BOOST_ROOT=/opt/boost_1_33_1<br>BOOST_INCLUDE=/usr/local/include/boost-1_33_1<br>BOOST_LIB=/usr/local/lib<br></pre>
<br>为了使其能够在登录时自动导入，你可以写一个脚本：<br>
<pre style="WHITE-SPACE: normal">#!/bin/sh<br>#boost settings<br>BOOST_ROOT=/opt/boost_1_33_1<br>BOOST_INCLUDE=/usr/local/include/boost-1_33_1<br>BOOST_LIB=/usr/local/lib<br>export BOOST_ROOT BOOST_INCLUDE BOOST_LIB<br></pre>
<br>将其保存为/etc/profile.d/boost.sh，并使用chmod a+x boost.sh设置执行权限。<br><br>现在我们可以写两段代码来测试了。<br><br>第一个测试文件是lex.cpp：<br><br>
<pre style="WHITE-SPACE: normal">#include &lt;boost/lexical_cast.hpp&gt;<br>#include &lt;iostream&gt;<br><br>int main()<br>{<br>using boost::lexical_cast;<br>int a = lexical_cast&lt;int&gt;("123");<br>double b = lexical_cast&lt;double&gt;("123.12");<br>std::cout&lt;&lt;a&lt;&lt;std::endl;<br>std::cout&lt;&lt;b&lt;&lt;std::endl;<br>return 0;<br>}<br></pre>
<br>编译：<br>
<pre style="WHITE-SPACE: normal">g++ lex.cpp -I$BOOST_ROOT -o lex</pre>
<br>运行：<br>
<pre style="WHITE-SPACE: normal">./lex</pre>
<br>输出：<br>
<pre style="WHITE-SPACE: normal">123<br>123.12<br></pre>
<br>你可以将$BOOST_ROOT改为$BOOST_INCLUDE，如果你没有设置环境变量，可以改为/opt/boost_1_33_1或者/usr/local/include/boost-1_33_1。<br><br>我们的第二个例子是re.cpp：<br><br>
<pre style="WHITE-SPACE: normal">#include &lt;iostream&gt;<br>#include &lt;string&gt;<br>#include &lt;boost/regex.hpp&gt;<br><br>int main() {<br><br>std::string s = "who,lives:in-a,pineapple under the sea?";<br><br>boost::regex re(",|:|-|\\s+");<br>boost::sregex_token_iterator<br>p(s.begin( ), s.end( ), re, -1);<br>boost::sregex_token_iterator end;<br><br>while (p != end)<br>std::cout &lt;&lt; *p++ &lt;&lt; '\n';<br>}<br></pre>
<br>编译：<br>
<pre style="WHITE-SPACE: normal">g++ re.cpp -I$BOOST_ROOT -lboost_regex-gcc -o re</pre>
<br>运行：<br>
<pre style="WHITE-SPACE: normal">./re</pre>
<br>输出：<br>
<pre style="WHITE-SPACE: normal">who<br>lives<br>in<br>a<br>pineapple<br>under<br>the<br>sea?<br></pre>
<br>这里要使用-l指定了链接库。<br><br>现在boost的基本安装配置已经完成，但是我们可以再改进下。<br><br>如果不想每次都指定boost头文件目录，可以将其link到/usr/include中：<br><br>
<pre style="WHITE-SPACE: normal">ln -s /opt/boost_1_33_1/boost /usr/include/boost<br></pre>
<br>或者：<br><br>
<pre style="WHITE-SPACE: normal">ln -s /usr/local/include/boost-1_33_1/boost /usr/include/boost<br></pre>
<br>如果你依然嫌boost编译后占用的空间太大，可以在boost目录下使用bjam clean：<br>
<pre style="WHITE-SPACE: normal">cd /opt/boost_1_33_1<br>bjam -sTOOLS=gcc clean<br></pre>
<br>这个命令会清除编译时的中间文件，/usr/local/lib下带版本号的boost libs，和/usr/local/include下的boost头文件。但是同时节省了几百M的硬盘空间。<br><br>所以如果你使用了clean，记得将BOOST_INCLUDE更为BOOST_ROOT（/opt/boost_1_33_1），将 /usr/include/boost link到/opt/boost_1_33_1/boost，再有就是编译链接时的boost lib不要带版本号。<br><br>如果你觉得编译时手动链接敲那么长的名字比较麻烦，可以使用脚本来自动寻找链接：<br><br>
<pre style="WHITE-SPACE: normal">#!/usr/bin/python<br><br>import os<br>import sys<br>import re<br><br>BOOST_ROOT = os.getenv('BOOST_ROOT')<br>BOOST_LIB = os.getenv('BOOST_LIB')<br>#BOOST_ROOT = '/opt/boost_1_33_1'<br>#BOOST_LIB = '/usr/local/lib'<br><br>def getlibs():<br>alls = os.listdir(BOOST_LIB)<br>libpattern = re.compile(r'^libboost_([^-]+)-gcc')<br>libs = {}<br>for lib in alls:<br>m = libpattern.match(lib)<br>if m:<br>libs[m.group(1).lower()] = 1<br>return libs<br><br><br>pattern = re.compile(r'^\s*#include\s*&lt;\s*boost/(.+)\.(h|hpp)\s*&gt;')<br>libs = getlibs()<br>libskeys = libs.keys()<br>includes = {}<br><br>ENV = os.environ<br><br><br>ARGV = sys.argv[1:]<br>files = ARGV<br>if len(files) == 0:<br>sys.exit()<br><br>for f in files:<br>if f.lower().endswith('.cpp'):<br>fp = open(f, 'r')<br>lines = fp.readlines()<br>for ln in lines:<br>m = pattern.match(ln)<br>if m:<br>libname = m.group(1).lower()<br>if libname in libskeys:<br>includes[libname] = 1<br><br>libline = ' '.join(map(lambda lib: '-lboost_'+lib+'-gcc', includes.keys()))<br><br><br>obj = ARGV[0]<br>obj = obj[:len(obj)-4]<br><br>#cmd = 'g++ %s -I%s %s -o %s' % (' '.join(files), BOOST_ROOT, libline, obj)<br>cmd = 'g++ %s %s -o %s' % (' '.join(files), libline, obj)<br><br>print cmd<br>os.system(cmd)<br></pre>
<br>将这段代码写进/usr/local/bin/gccboost，赋予执行权限。<br><br>使用方法：<br>
<pre style="WHITE-SPACE: normal">gccboost lex.cpp<br>gccboost re.cpp<br></pre>
<br>注意：使用此命令假设boost头文件在/usr/include中，如果假设不成立，请自行修改脚本此行：<br>
<pre style="WHITE-SPACE: normal">cmd = 'g++ %s %s -o %s' % (' '.join(files), libline, obj)</pre>
<br>为之前的注释行：<br>
<pre style="WHITE-SPACE: normal">cmd = 'g++ %s -I%s %s -o %s' % (' '.join(files), BOOST_ROOT, libline, obj)</pre>
<br>如若BOOST_ROOT和BOOST_LIB环境变量不存在，修改下面两行代码：<br>
<pre style="WHITE-SPACE: normal">BOOST_ROOT = os.getenv('BOOST_ROOT')<br>BOOST_LIB = os.getenv('BOOST_LIB')<br></pre>
<br>为之后注释行：<br>
<pre style="WHITE-SPACE: normal">BOOST_ROOT = '/opt/boost_1_33_1'<br>BOOST_LIB = '/usr/local/lib'<br></pre>
<br>另外，gccboost将会自动修改输出的文件名为*.cpp的文件名（如lex.cpp将输出lex），如果不需要，请将下面的代码：<br>
<pre style="WHITE-SPACE: normal">cmd = 'g++ %s %s -o %s' % (' '.join(files), libline, obj)</pre>
<br>改为：<br>
<pre style="WHITE-SPACE: normal">cmd = 'g++ %s %s' % (' '.join(files), libline)</pre>
<br><br>Boost安装历程至此基本结束。</span></span>
<img src ="http://www.cppblog.com/lovefeel2004/aggbug/116943.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lovefeel2004/" target="_blank">幽梦新影</a> 2010-06-01 23:36 <a href="http://www.cppblog.com/lovefeel2004/archive/2010/06/01/116943.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>在Linux系统中安装和配置ACE(转)</title><link>http://www.cppblog.com/lovefeel2004/archive/2010/06/01/116942.html</link><dc:creator>幽梦新影</dc:creator><author>幽梦新影</author><pubDate>Tue, 01 Jun 2010 15:31:00 GMT</pubDate><guid>http://www.cppblog.com/lovefeel2004/archive/2010/06/01/116942.html</guid><wfw:comment>http://www.cppblog.com/lovefeel2004/comments/116942.html</wfw:comment><comments>http://www.cppblog.com/lovefeel2004/archive/2010/06/01/116942.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/lovefeel2004/comments/commentRss/116942.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/lovefeel2004/services/trackbacks/116942.html</trackback:ping><description><![CDATA[<span class=Apple-style-span style="WORD-SPACING: 0px; FONT: medium Simsun; TEXT-TRANSFORM: none; COLOR: rgb(0,0,0); TEXT-INDENT: 0px; WHITE-SPACE: normal; LETTER-SPACING: normal; BORDER-COLLAPSE: separate; orphans: 2; widows: 2; webkit-border-horizontal-spacing: 0px; webkit-border-vertical-spacing: 0px; webkit-text-decorations-in-effect: none; webkit-text-size-adjust: auto; webkit-text-stroke-width: 0px"><span class=Apple-style-span style="FONT-SIZE: 14px; COLOR: rgb(50,62,50); LINE-HEIGHT: 21px; FONT-FAMILY: simsun, 宋体, sans-serif; TEXT-ALIGN: left">
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal">本文详细描述了在Linux操作系统上安装和配置&#8220;自适应通信环境(ACE)&#8221;的过程和注意事项。<br>文中的描述基于RedHat Linux 9操作系统和ACE 5.4版</p>
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal">&nbsp;<wbr></p>
准备工作：
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal">&nbsp;<wbr></p>
1.确保你的Linux操作系统的开发环境(gcc、make&#8230;&#8230;)是完整且可用的。<br>2.在安装ACE的过程中，可能需要root权限，因此确保你拥有root帐户的密码。<br>3.对于典型的Redhat9系统，autoconf程序的版本可能过低，你需要首先升级它。
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal">&nbsp;<wbr></p>
&nbsp;<wbr>&nbsp;<wbr><span class=Apple-converted-space>&nbsp;</span>升级的步骤如下：
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal">&nbsp;<wbr></p>
1.在控制台中输入 autoconf -V，查看你的autoconf程序的版本<br>2.如果低于2.57g，你需要到<a style="COLOR: rgb(49,139,146); TEXT-DECORATION: none" href="http://www.gnu.org/software/autoconf/" target=_blank></a><a style="COLOR: rgb(49,139,146); TEXT-DECORATION: none" href="http://www.gnu.org/software/autoconf/" target=_blank>http://www.gnu.org/software/autoconf/</a>去下载最新版本的autoconf程序，目前autoconf程序的版本是2.59<br>3.根据tarball中的安装说明，编译并安装升级autoconf程序<br>开始安装：
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal">&nbsp;<wbr></p>
经过上面的准备工作，现在你已经具备了安装ACE的条件。下面开始正式的安装工作。
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal">&nbsp;<wbr></p>
1.首先确定ACE的安装路径，并建立相应的目录。<br>这里，我们把ACE安装在/home/zhc/ace/的目录下，先执行<br>mkdir /home/zhc/ace<br>2.然后将获得的ACE源代码包解至该目录下。<br>tar zxvf ACE-5.4.tar.gz /home/zhc/ace<br>3.这时，在ace的目录下会建立一个名为ACE_wrappers的子目录，ACE所有的源代码、工具、和例子都在这个目录中。<br>先进入该目录，执行<br>cd /home/zhc/ace/ACE_wrappers<br>然后建立一个子目录，用于存放ACE编译后的目标文件<br>mkdir build<br>cd build<br>4.接着,执行configure脚本，检查你的系统环境，配置并生成适合你的系统的Makefile文件。<br>在执行configure脚本时，可以加入许多配置选项，其详细说明可以参看ACE_wrappers目录下的ACE-INSTALL.html文件，<br>对于Redhat9系统来说，不必加任何参数，ACE就可以很好的工作了。<br>../configure<br>5.在漫长的检查和配置之后，如果没有什么问题，你就可以开始编译了（如果要让ace支持ICMP 和对c++库的支持，需要在config.h头文件中加上#define ACE_HAS_STANDARD_CPP_LIBRARY 1 和#define ACE_HAS_ICMP_SUPPORT 1）。<br>这一步很简单，执行<br>make<br>然后，泡一杯茶，静静的等待就行了。<br>6.如果编译顺利的通过(通常都会是这样的)，那么恭喜你，你已经成功了一大半了，下面要做的仅仅是以些配置工作而已。<br>接下来的工作是安装，这一步是可选的，目的是把编译生成的ACE的库文件、头文件和手册页等安装到/usr/local的相应目录中去，为了今后使用的方便，我建议你还是进行这一步，执行<br>su<br>root's password<br>make install<br>7.安装之后，我们就可以进行最后的配置工作了。<br>首先设置环境变量ACE_ROOT，执行<br>setenv ACE_ROOT /home/zhc/ace/ACE_wrappers<br>注意其中的路径要根据你的实际情况而定<br>如果你不想每次都手工设定路径，可以编辑你的bash的配置文件，执行<br>cd<br>vi .bash_profile<br>在其中填加如下两行<br>ACE_ROOT=/home/work/research/ace/ACE_wrappers<br>export ACE_ROOT<br>8.然后，在$ACE_ROOT/ace目录中创建一个名为config.h的文件，在其中包含如下一行<br>#include "ace/config-linux.h"<br>或者，简单起见，你也可以直接建立一个指向config-linux.h的符号链接，执行<br>ln -s config-linux.h config.h<br>9.同样，在$ACE_ROOT/include/makeinclude目录中创建一个名为platform_macros.GNU的文件，在其中包含如下一行<br>include $(ACE_ROOT)/include/makeinclude/platform_linux.GNU<br>或者，简单起见，你也可以直接建立一个指向platform_linux.GNU的符号链接，执行<br>ln -s platform_linux.GNU platform_macros.GNU<br>10.最后一步，设置环境变量LD_LIBRARY_PATH，执行<br>setenv LD_LIBRARY_PATH $ACE_ROOT/ace:$ACE_ROOT/lib:<br>/usr/local/lib:$LD_LIBRARY_PATH<br>或者在~/.bash_profile文件中添加如下两行<br>LD_LIBRARY_PATH=$ACE_ROOT/ace:$ACE_ROOT/lib:<br>/usr/local/lib:$LD_LIBRARY_PATH<br>export LD_LIBRARY_PATH<br>安装完成：
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal">&nbsp;<wbr></p>
经过上面的步骤，ACE已经安装到了您的系统上了，下面我们将编译并执行ACE的例程以验证我们的工作。<br>这里我们以《C++网络编程，卷一》所带的例子为例。
<p style="BORDER-TOP-WIDTH: 0px; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; BORDER-LEFT-WIDTH: 0px; BORDER-BOTTOM-WIDTH: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px 0px 5px; WORD-BREAK: normal; LINE-HEIGHT: 21px; PADDING-TOP: 0px; LIST-STYLE-TYPE: none; BORDER-RIGHT-WIDTH: 0px; WORD-WRAP: normal">&nbsp;<wbr></p>
1:进入例程目录，执行<br>cd $(ACE_ROOT)/examples/C++NPv1<br>2:编译例子程序，执行<br>make<br>如果前面的安装和配置正确，很快就能够得到编译后的例子程序。<br>3:分别执行一个服务器程序(随便哪一个都行)和一个客户端程序(Logging_Client)，如果程序运行正确，说明前面的安装和配置成功，下面你就可以开始你的ACE学习之旅了</span></span>
<img src ="http://www.cppblog.com/lovefeel2004/aggbug/116942.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/lovefeel2004/" target="_blank">幽梦新影</a> 2010-06-01 23:31 <a href="http://www.cppblog.com/lovefeel2004/archive/2010/06/01/116942.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>