`
javasogo
  • 浏览: 1774960 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

STL实践指南(下)

阅读更多

STL实践指南 Practical Guide to STL
作者:Jeff Bogan
翻译:周翔

(接中篇)

游标(Iterator)

我说过游标是指针,但不仅仅是指针。游标和指针很像,功能很像指针,但是实际上,游标是通过重载一元的”*”和”->”来从容器中间接地返回一个值。将这些值存储在容器中并不是一个好主意,因为每当一个新值添加到容器中或者有一个值从容器中删除,这些值就会失效。在某种程度上,游标可以看作是句柄(handle)。通常情况下游标(iterator)的类型可以有所变化,这样容器也会有几种不同方式的转变:
iterator——对于除了vector以外的其他任何容器,你可以通过这种游标在一次操作中在容器中朝向前的方向走一步。这意味着对于这种游标你只能使用“++”操作符。而不能使用“--”或“+=”操作符。而对于vector这一种容器,你可以使用“+=”、“—”、“++”、“-=”中的任何一种操作符和“<”、“<=”、“>”、“>=”、“==”、“!=”等比较运算符。
reverse_iterator ——如果你想用向后的方向而不是向前的方向的游标来遍历除vector之外的容器中的元素,你可以使用reverse_iterator 来反转遍历的方向,你还可以用rbegin()来代替begin(),用rend()代替end(),而此时的“++”操作符会朝向后的方向遍历。
const_iterator ——一个向前方向的游标,它返回一个常数值。你可以使用这种类型的游标来指向一个只读的值。
const_reverse_iterator ——一个朝反方向遍历的游标,它返回一个常数值。

Set和Map中的排序

除了类型和值外,模板含有其他的参数。你可以传递一个回调函数(通常所说的声明“predicate”——这是带有一个参数的函数返回一个布尔值)。例如,如果你想自动建立一个集合,集合中的元素按升序排列,你可以用简明的方法建立一个set类:

set <int, greater<int> > set1

greater <int>是另一个模板函数(范型函数),当值放置在容器中后,它用来为这些值排序。如果你想按降序排列这些值,你可以这样写:</int>

set <int, less<int> > set1

在实现算法时,将声明(predicate)作为一个参数传递到一个STL模板类中时会遇到很多的其他情况,下面将会对这些情况进行详细描述。

STL 的烦恼之二——错误信息

这些模板的命名需要对编译器进行扩充,所以当编译器因某种原因发生故障时,它会列出一段很长的错误信息,并且这些错误信息晦涩难懂。我觉得处理这样的难题没有什么好办法。但最好的方法是去查找并仔细研究错误信息指明代码段的尾端。还有一个烦恼就是:当你双击错误信息时,它会将错误指向模版库的内部代码,而这些代码就更难读了。一般情况下,纠错的最好方法是重新检查一下你的代码,运行时忽略所有的警告信息。

算法(Algorithms)

算法是模板中使用的函数。这才真正开始体现STL的强大之处。你可以学习一些大多数模板容器中都会用到的一些算法函数,这样你可以通过最简便的方式进行排序、查找、交换等操作。STL中包含着一系列实现算法的函数。比如:sort(vec.begin()+1, vec.end()-1)可以实现对除第一个和最后一个元素的其他元素的排序操作。
容器自身不能使用算法,但两个容器中的游标可以限定容器中使用算法的元素。既然这样,算法不直接受到容器的限制,而是通过采用游标,算法才能够得到支持。此外,很多次你会遇到传递一个已经准备好了的函数(以前提到的声明:predicate)作为参数,你也可以传递以前的旧值。
下面的例子演示了怎样使用算法:

//程序:测试分数统计
//目的:通过对向量中保存的分数的操作说明怎样使用算法

#include <algorithm>&lt;algorithm&gt; //如果要使用算法函数,你必须要包含这个头文件。<br>#include &lt;numeric&gt; // 包含accumulate(求和)函数的头文件<br>#include &lt;vector&gt;<br>#include &lt;iostream&gt;<br>using namespace std;</algorithm>

int testscore[] = {67, 56, 24, 78, 99, 87, 56};

//判断一个成绩是否通过了考试
bool passed_test(int n)
{
return (n >= 60);
}

// 判断一个成绩是否不及格
bool failed_test(int n)
{
return (n < 60);
}

int main(int argc, char* argv[])
{
int total;
// 初始化向量,使之能够装入testscore数组中的元素
vector <int> vecTestScore(testscore,
testscore + sizeof(testscore) / sizeof(int));
vector <int>::iterator vi;

// 排序并显示向量中的数据
sort(vecTestScore.begin(), vecTestScore.end());
cout << "Sorted Test Scores:" << endl;
for (vi=vecTestScore.begin(); vi != vecTestScore.end(); vi++)
{ cout << *vi << ", "; }
cout << endl;

// 显示统计信息

// min_element 返回一个 _iterator_ 类型的对象,该对象指向值最小的那个元素。
//“*”运算符提取元素中的值。
vi = min_element(vecTestScore.begin(), vecTestScore.end());
cout << "The lowest score was " << *vi << "." << endl;

//与min_element类似,max_element是选出最大值。
vi = max_element(vecTestScore.begin(), vecTestScore.end());
cout << "The highest score was " << *vi << "." << endl;

// 使用声明函数(predicate function,指vecTestScore.begin()和vecTestScore.end())来确定通过考试的人数。
cout << count_if(vecTestScore.begin(), vecTestScore.end(), passed_test) <<
" out of " << vecTestScore.size() <<
" students passed the test" << endl;

// 确定有多少人考试挂了
cout << count_if(vecTestScore.begin(),
vecTestScore.end(), failed_test) <<
" out of " << vecTestScore.size() <<
" students failed the test" << endl;

//计算成绩总和
total = accumulate(vecTestScore.begin(),
vecTestScore.end(), 0);
// 计算显示平均成绩
cout << "Average score was " <<
(total / (int)(vecTestScore.size())) << endl;

return 0;
}

Allocator(分配器)

Allocator用在模板的初始化阶段,是为对象和数组进行分配内存空间和释放空间操作的模板类。它在各种情况下扮演着很神秘的角色,它关心的是高层内存的优化,而且对黑盒测试来说,使用Allocator是最好的选择。通常,我们不需要明确指明它,因为它们通常是作为不用添加的缺省的参数出现的。如果在专业的测试工作中出现了Allocator,你最好搞清楚它是什么。

Embed Templates(嵌入式模版)和Derive Templates(基模板)

每当你使用一个普通的类的时候,你也可以在其中使用一个STL类。它是可以被嵌入的:

class CParam
{
string name;
string unit;
vector <double> vecData;
};

或者将它作为一个基类:

class CParam : public vector <double>
{
string name;
string unit;
};

STL模版类作为基类时需要谨慎。这需要你适应这种编程方式。

模版中的模版

为构建一个复杂的数据结构,你可以将一个模板植入另一个模板中(即“模版嵌套”)。一般最好的方法是在程序前面使用typedef关键字来定义一个在另一个模板中使用的模版类型。

// 程序:在向量中嵌入向量的演示。
//目的:说明怎样使用嵌套的STL容器。

#include <iostream>
#include <vector>

using namespace std;

typedef vector <int> VEC_INT;

int inp[2][2] = {{1, 1}, {2, 0}};
// 要放入模板中的2x2的正则数组

int main(int argc, char* argv[])
{
int i, j;
vector <VEC_INT> vecvec;
// 如果你想用一句话实现这样的嵌套,你可以这样写:
// vector <vector <int> > vecvec;

// 将数组填入向量
VEC_INT v0(inp[0], inp[0]+2);
// 传递两个指针
// 将数组中的值拷贝到向量中
VEC_INT v1(inp[1], inp[1]+2);

vecvec.push_back(v0);
vecvec.push_back(v1);

for (i=0; i<2; i++)
{
for (j=0; j<2; j++)
{
cout << vecvec[i][j] << " ";
}
cout << endl;
}
return 0;
}

// 输出:
// 1 1
// 2 0

虽然在初始化时很麻烦,一旦你将数据填如向量中,你就实现了一个变长的可扩充的二维数组(大小可扩充直到使用完内存)。根据实际需要,可以使用各种容器的嵌套组合。

总结

STL是有用的,但是使用过程中的困难和麻烦是再所难免的。就像中国人所说的:“如果你掌握了它,便犹如虎添翼。”

相关链接:
Josuttis Website :http://www.josuttis.com/
Pretty Good Initialization Library :http://www.codeproject.com/vcpp/stl/PGIL.asp

(全文完)

分享到:
评论

相关推荐

    STL实践指南 STL实践指南 STL实践指南 STL实践指南

    STL实践指南 STL实践指南 STL实践指南 STL实践指南

    STL实践指南-pdf

    这个不用我多说了吧,好东西哦.stl实践指南

    STL实践指南.doc

    STL实践指南.doc

    STL实践指南 Practical Guide to STL

    STL实践指南 Practical Guide to STL 让你快速入门,省去垃圾冗余的介绍,强烈推荐! 并有实例教程及其运行源码附带! STL完美体现,君请下载!物有所值

    STL实践指南

    STL实践指南

    STL实践指南.rar

    这篇文章从STL的基础知识讲起,循序渐进,逐步深入,涉及到了STL编写代码的方法、STL代码的编译和调试、命名空间(namespace)、STL中的ANSI / ISO字符串、各种不同类型的容器(container)、模板(template)、游标...

    STL实践指南,初学者的法宝

    对C++初学者比较有用,可以很快的入门STL。

    C++ STL书籍集

    微软C编程精粹(doc),高质量c++编程(pdf和doc),Effective c++(chm),More Effective c++(doc和pdf),STL实践指南(doc),Effective STL(pdf),WindowsProgramming.chm,Effective STL读书笔记.doc ...

    STL 入门最全的资料

    这是一篇指导您如何在Microsoft Visual Studio下学习STL并进行实践的文章。这篇文章从STL的基础知识讲起,循序渐进,逐步深入,涉及到了STL编写代码的...不仅仅适合初学者学习STL,更是广大读者使用STL编程的实践指南。

    C++ STL 资料包大全

    STL 资料包 里面有:STL.pdf 、STL实践指南.doc、STL.源码剖析.zip】Effective_STL_cn.pdf,都是从网上收集方便大家查找。绝对值得下载。 顺便介绍个很不错的C++网站:...

    WINDOWS STL编程

    这是一篇指导您如何在Microsoft Visual Studio下学习STL并进行实践的文章。这篇文章从STL的基础知识讲起,循序渐进,逐步深入,涉及到了STL编写代码的...不仅仅适合初学者学习STL,更是广大读者使用STL编程的实践指南。

    CC++VCSTL书籍和算法

    微软C编程精粹(doc),高质量c++编程(pdf和doc),Effective c++(chm),More Effective c++(doc和pdf),STL实践指南(doc),Effective STL(pdf),WindowsProgramming.chm,Effective STL读书笔记.doc ...

    高质量 C++/C 编程指南

    , 涵盖了C++程序设计的每一个方面,包括设计和编码风格、函数、操作符、类的设计、继承、构造与析构、赋值、名字空间、模块、模板、泛型、异常、STL容器和算法等。书中对每一条规范都给出了言简意赅的叙述,并辅以...

    C++书籍集合

    本书对C++基本概念、技术、以及现代C++编程风格进行了全面而且权威的阐述,是C++初学者的最佳指南;本书可以帮助你编写实用的程序,而无需首先精通每个语言细节。对于中高级程序员,本书也是不可或缺的参考书。 ...

    c++精粹c++精粹c++精粹c++精粹

    这本书不仅仅是一本简明的参考指南或是对一个复杂课题的简单小结,Pohl博士在经过缜密思考之后,加入他对C++语言的使用及编程风格的独特建议,这些建议包含了对这门语言所做的更为深入的探索,尤其在专业实践方面。...

    C++ 编程思想 文档版转成 非扫描

    本书介绍C++实用的编程技术和最佳的实践方法,深入探究了异常处理方法和异常安全设计;介绍C++的字符串、输入输出流、STL算法、容器和模板的现代用法,包括模板元编程;解释多重继承问题的难点,展示RTTI的实际使用...

    C++编程思想 第2卷 实用编程技术

    ·介绍实用的编程技术和最佳的实践方法,解决C++开发中最困难的课题。 ·深入研究标准C++库的功能,包括:字符串、输入输出流、STL算法和容器。 ·讲述模板的现代用法,包括模板元编程。 ·解开对多继承的困惑,展示...

    推荐C++书目.doc推荐C++书目.doc

    23、《高质量程序设计指南——C++/C 》2nd (林锐 韩永泉) 24、《C++ 程序设计教程》2nd(钱能) 25、《The Design and Evolution of C++》(Bjarne Stroustrup) 26、《面向对象编程C++和Java比较教程》(Aviansh ...

Global site tag (gtag.js) - Google Analytics