c primer中文版(第4版)(中英对照)4_第1页
c primer中文版(第4版)(中英对照)4_第2页
c primer中文版(第4版)(中英对照)4_第3页
c primer中文版(第4版)(中英对照)4_第4页
c primer中文版(第4版)(中英对照)4_第5页
已阅读5页,还剩207页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

C++Primer中文版(第4版)(中英对照)四

PartII:ContainersandAlgorithms

第二部分:容器和算法

We'vesaidthatC++isaboutefficientprogrammingwithabstractions.TheStandardLibraryisa

goodexample:Thelibrarydefinesanumberofcontainerclassesandafamilyofgenericalgorithms

thatletuswriteprogramsthataresuccinct,abstract,andefficient.Thelibraryworriesabout

bookkeepingdetailsinparticular,takingcareofmemorymanagementsothatourprogramscanworry

abouttheactualproblemsweneedtosolve.

C++提供了使用抽象进行高效率编程的方式。标准库就是一个很好的例子:标准库定义了许多容器类以及一

系列泛型算法,使程序员可以更简洁、抽象和有效地编写程序。这样可以让标准库操心那些繁琐的细节,特

别是内存管理,我们的程序只需要关注要解决的实际问题就行了。

InChapter3weintroducedthevectorcontainertype.We'11learnmoreinChapter9aboutvector

andtheothersequentialcontainertypesprovidedbythelibrary.We'11alsocovermoreoperations

providedbythestringtype.Wecanthinkofastringasaspecialkindofcontainerthatcontains

onlycharacters.Thestringtypesupportsmany,butnotall,ofthecontaineroperations.

第三章介绍了vector容器类型。我们将会在第九章进•步探讨vector和其他顺序容器类型,而且还会学

习string类型提供的更多操作,这些容器类型都是由标准库定义的。我们可将string视为仅包含字符的

特殊容器,string类型提供大量(但并不是全部)的容器操作。

Thelibraryalsodefinesseveralassociativecontainers.Elementsinanassociativecontainerare

orderedbykeyratherthansequentially.Theassociativecontainerssharemanyoperationswith

thesequentialcontainersandalsodefineoperationsthatarespecifictotheassociative

containers.TheassociativecontainersarecoveredinChapter10.

标准库还定义了儿种关联容器。关联容器中的元素不是顺序排列,而是按键(key)排序的。关联容器共享

了许多顺序容器提供的操作,止匕外,还定义了自己特殊的操作。我们将在第十章学习相关的内容。

Chapter11introducesthegenericalgorithms.Thealgorithmstypicallyoperateonarangeof

elementsfromacontainerorothersequence.Thealgorithmslibraryoffersefficient

implementationsofvariousclassicalalgorithms,suchassearching,sorting,andothercommon

tasks.Forexample,thereisacopyalgorithm,whichcopieselementsfromonesequencetoanother;

find,whichlooksforagivenelement;andsoon.Thealgorithmsaregenericintwoways:They

theycanbeappliedtodifferentkindsofcontainers,andthosecontainersmaycontainelements

ofmosttypes.

第十•章介绍了泛型算法,这些算法通常作用于容器或序列中某一范围的元素。算法库提供了各种各样经典

算法的有效实现,像查找、排序及其他常见的算法任务。例如,复制算法将一个序列中所有所元素复制到另

一个序列中;查找算法则用于寻找一个指定元素,等等。泛型算法中,所谓“泛型(generic)”指的是两

个方面:这些算法可作用于各种不同的容器类型,而这些容器乂可以容纳多种不同类型的元素。

Thelibraryisdesignedsothatthecontainertypesprovideacommoninterface:Iftwocontainers

offerasimilaroperation,thenthatoperationwi11bedefinedidenticallyforbothcontainers.

Forexample,allthecontainershaveanoperationtoreturnthenumberofelementsinthecontainer.

Allthecontainersnamethatoperationsize,andtheyalldefineatypenamedsizetypethatis

thetypeofthevaluereturnedbysize.Similarly,thealgorithmshaveaconsistentinterface.

Forexample,mostalgorithmsoperateonarangeofelementsspecifiedbyapairofiterators.

为容器类型提供通用接口是设计库的目的。如果两种容器提供相似的操作,则为它们定义的这个操作应该完

全相同。例如,所有容器都有返回容器内元素个数的操作,于是所有容器都将操作命名为size,并将size返

同值的类型都指定为size_type类型。类似地,算法具有一致的接口。例如,大部分算法都作用在由一对

迭代器指定的元素范围上。

Becausethecontaineroperationsandalgorithmsaredefinedconsistently,learningthelibrary

becomeseasier:Onceyouunderstandhowanoperationworks,youcanapplythatsameoperationto

othercontainers.Moreimportantly,thiscommonalityofinterfaceleadstomoreflexibleprograms.

Itisoftenpossibletotakeaprogramwrittentouseoneconteiinertypeandchangeittousea

differentcontainerwithouthavingtorewritecode.Aswe’11see,thecontainersofferdifferent

performancetradeoffs,andtheabilitytochangecontainertypescanbevaluablewhenfine-tuning

theperformanceofasystem.

容器提供的操作和算法是一致定义的,这使得学习标准库更容易:只需理解一个操作如何工作,就能将该操

作应用于其他的容器。更重要的是,接口的•致性使程序变得更灵活。通常不需要重新编写代码,就可以将

一段使用某种容器类型的程序修改为使用不同容器实现。正如我们所看到的,容器提供了不同的性能折衷方

案,可以改变容器类型对优化系统性能来说颇有价值。

CONTENTS

目录

Chapter9SequentialContainers

Chapter10AssociativeContainers

Chapter11GenericAlgorithms

Chapter9.SequentialContainers

CONTENTS

目录

Seclion9.1DefiningaSequentialContainer307

Seelion9.2IteratorsandIteratorRanges311

SQgiiop9.3SequenceContainerOperations316

Scc[iQp9.4HowavectorGrows330

Section9.5DecidingWhichContainertoUse333

Section9.6stringsRevisited335

Section9.7ContainerAdaptors348

ChapterSummary353

DefinedTerms353

Thischaptercompletesourdiscussionofthestandard-1ibrarysequentialcontainertypes.It

expandsonthematerialfromChaplcr3,whichintroducedthemostcommonlyusedsequential

container,thevectortype.Elementsinasequentialcontainerarestoredandaccessedbyposition.

Thelibraryalsodefinesseveralassociativecontainers,whichholdelementswhoseorderdepends

onakey.Associativecontainersarecoveredinthenextchapter.

第二堂介绍了最常用的顺序容器:vector类型。本章将对第三章的内容进行扩充和完善,继续讨论标准库

提供的顺序容器类型。顺序容器内的元素按其位置存储和访问。除顺序容器外,标准库还定义了儿种关联容

器,其元素按键(key)排序。我们将在下一章讨论它们。

Thecontainerclassesshareacommoninterface.Thisfactmakesthelibraryeasiertolearn;what

welearnaboutonetypeappliestoanother.Eachcontainertypeoffersadifferentsetoftime

andfunctionalitytradeoffs.Oftenaprogramusingonetypecanbefine-tunedbysubstituting

anothercontainerwithoutchangingourcodebeyondtheneedtochangetypedeclarations.

容器类共享公共的接口,这使标准库更容易学习,只要学会其中一种类型就能运用另种类型。每种容器类

型提供一组不同的时间和功能折衷方案。通常不需要修改代码,只需改变类型声明,用一种容器类型替代另

一种容器类型,就可以优化程序的性能。

Acontainerholdsacollectionofobjectsofaspecifiedtype.We'veusedonekindofcontainer

already:thelibraryvectortype.Itisasequentialcontainer.Itholdsacollectionofelements

ofasingletype,makingitacontainer.Thoseelementsarestoredandaccessedbyposition,making

itasequentialcontainer.Theorderofelementsinasequentialcontainerisindependentofthe

valueoftheelements.Instead,theorderisdeterminedbytheorderinwhichelementsareadded

tothecontainer.

容器容纳特定类型对象的集合。我们已经使用过种容器类型:标准库vector类型,这是种顺序容器

(sequentialcontainer)°它将单一类型元素聚集起来成为容器,然后根据位置来存储和访问这些元素,

这就是顺序容器。顺序容器的元素排列次序与元素值无关,而是由元素添加到容器里的次序决定。

The1ibrarydefinesthreekindsofsequentialcontainers:vector,list,anddeque(shortfor

“double-endedqueue“andpronounced"deck").Thesetypesdifferinhowelementsareaccessedand

therelativerun-timecostofaddingorremovingelements.The1ibraryalsoprovidesthreecontainer

adaptors.Effectively,anadaptoradaptsanunderlyingcontainertypebydefininganewinterface

intermsoftheoperationsprovidedbytheoriginaltype.Thesequentialcontaineradaptorsare

stack,queue,andpriorityqueue.

标准库定义了三种顺序容器类型:vector、list和deque(是双端队列"double-endedqueue”的简写,

发音为“deck”)。它们的差别在于访问元素的方式,以及添加或删除元素相关操作的运行代价。标准库还

提供了三种容器适配器(adaptors)0实际上,适配器是根据原始的容器类型所提供的操作,通过定义新的

操作接口,来适应基础的容器类型。顺序容器适配器包括stack.queue和priorityqueue类型,见表一91。

Containersdefineonlyasmallnumberofoperations.Manyadditionaloperationsareprovidedby

thealgorithmslibrary,whichwe'11coverinChapter11.Forthoseoperationsthataredefined

bythecontainers,thelibraryimposesacommoninterface.Thecontainersvaryastowhich

operationstheyprovide,butiftwocontainersprovidethesameoperation,thentheinterface(name

andnumberofarguments)willbethesameforbothcontainertypes.Thesetofoperationsonthe

containertypesformakindofhierarchy:

容器只定义了少量操作。大多数额外操作则由算法库提供,我们将在第十•章学习算法库。标准库为由容器

类型定义的操作强加了公共的接口。这些容器类型的差别在于它们提供哪些操作,但是如果两个容器提供了

相同的操作,则它们的接口(函数名字和参数个数)应该相同。容器类型的操作集合形成了以下层次结构:

•Someoperationsaresupportedbyal1containertypes.

一些操作适用于所有容器类型。

•Otheroperationsarecommontoonlythesequentialoronlytheassociativecontainers.

另外一些操作则只适用于顺序或关联容器类型。

•Stillothersarecommontoonlyasubsetofeitherthesequentialorassociativecontainers.

还有一些操作只适用于顺序或关联容器类型的个子集。

Intheremainderofthischapter,welookatthesequentialcontainertypesandtheiroperations

indetail.

在本章的后续部分,我们将详细描述顺序容器类型和它们所提供的操作。

表9.L顺序容器类型

Table9.1.SequentialContainerTypes

SequentialContainers

顺序容器

vectorSupportsfastrandomaccess

支持快速随机访问

listSupportsfastinsertion/deletion

支持快速插入/删除

dequeDouble-endedqueue

双端队列

SequentialContainerAdaptors

顺序容器适配器

stackLastin/Firstoutstack

后进先出(LIFO)堆栈

queueFirstin/Firstoutqueue

先进先出(FIFO)队列

priorityqueuePriority-managedqueue

有优先级管理的队列

9.1.DefiningaSequentialContainer

9.1.顺序容器的定义

Wealreadyknowafairbitabouthowtousethesequentialcontainersbasedonwhatwecovered

inSection3.3(p.90).Todefineacontainerobject,wemustincludeitsassociatedheaderfile,

whichisoneof

在第3.3节中,我们已经了解了一些使用顺序容器类型的知识。为了定义一个容器类型的对象,必须先包

含相关的头文件,即下列头文件之一:

#include<vector>

#include<list>

#include<deque>

Eachofthecontainersisaclasstemplate(Section3.3,p.90).Todefineaparticularkindof

container,wenamethecontainerfollowedbyanglebracketsthatenclosethetypeoftheelements

thecontainerwillhold:

所有的容器都是类模板(第3.3节)o要定义某种特殊的容器,必须在容器名后加一对尖括号,尖括号里

面提供容器中存放的元素的类型:

vector<string>svec;//emptyvectorthatcanholdstrings

list<int>ilist;//emptylistthatcanholdints

deque<Sales_item>items;//emptydequethatholdsSales_items

Eachcontainerdefinesadefaultconstructorthatcreatesanemptycontainerofthespeicfiedtype.

Recallthatadefaultconstructortakesnoarguments.

所有容器类型都定义了默认构造函数,用于创建指定类型的空容器对象。默认构造函数不带参数。

Forreasonsthatshallbecomeclearshortly,themostcommonlyusedcontainer

constructoristhedefaultconstructor.Inmostprograms,usingthedefault

constructorgivesthebestrun-timeperformanceandmakesusingthecontainer

easier.

为了使程序更清晰、简短,容器类型最常用的构造函数是默认构造函数。在大多数的程

序中,使用默认构造函数能达到最佳运行时性能,并且使容器更容易使用。

9.1.1.InitializingContainerElements

9.1.1.容器元素的初始化

Inadditiontodefiningadefaultconstructor,eachcontainertypealsosupportsconstructorsthat

allowustospecifyinitialelementvalues.

除了默认构造函数,容器类型还提供其他的构造函数,使程序员可一以指定元素初值,见表9.2。

表9.2.容器构造函数

Table9.2.ContainerCreateanemptycontainernamedc.Cisacontainernagsuchasvector,

ConstructorsandTistheelementtype,suchasintorstring.Validforallcontainers.

C<T>c;创建一个名为c的空容器。C是容器类型名,如vector,T是元素类型,如int或

string适用于所有容器。

Cc(c2);Createcasacopyofcontainerc2;candc2mustbethesamecontainertype

andholdvaluesofthesametype.Validforallcontainers.

创建容器c2的副本c;c和c2必须具有相同的容器类型,并存放相同类型的元

素。适用于所有容器。

Cc(b,e);Createcwithacopyoftheelementsfromtherangedenotedbyiteratorsb

ande.Validforallcontainers.

创建c,其元素是迭代器b和e标示的范围内元素的副本。适用于所有容器。

Cc(n,t);Createcwithnelements,eachwithvaluet,whichmustbeavalueofthe

elementtypeofCoratypeconvertibletothattype.

用n个值为l的元素创建容器c,其中值t必须是容器类型C的元素类型的值,

或者是可转换为该类型的值。

Sequentialcontainersonly.

只适用于顺序容器

Cc(n);Createcwithnvalue-initialized(Section3.3.1,p.92)elements.

创建有n个值初始化(第3.3.1节)(value-initialized)元素的容器c0

Sequentialcontainersonly.

只适用于顺序容器

IntializingaContainerasaCopyofAnotherContainer

将一个容器初始化为另一个容器的副本

Whenweinitializeasequentialcontainerusinganyconstructorotherthanthedefaultconstructor,

wemustindicatehowmanyelementsthecontainerwillhave.Wemustalsosupplyinitialvalues

forthoseelements.Onewaytospecifyboththesizeandelement,valuesistoinitializeanew

containerasacopyofanexistingcontainerofthesametype:

当不使用默认构造函数,而是用其他构造函数初始化顺序容器时,必须指出该容器有多少个元素,并提供这

当元素的初值。同时指定元素个数和初值的•个方法是将新创建的容器初始化为•个同类型的已存在容器的

副本:

vector<int>ivec;

vector<int>ivec2(ivec);//ok:ivecisvector<int>

list<int>ilist(ivec);//error:ivecisnotlist<int>

vector<double>dvec(ivec);//error:ivecholdsintnotdouble

Whenwecopyonecontainerintoanother,thetypesmustmatchexactly:The

containertypeandelementtypemustbethesame.

将一个容器复制给另一个容器时,类型必须匹配:容器类型和元素类型都必须相同。

InitializingasaCopyofaRangeofElements

初始化为一段元素的副本

Althoughwecannotcopytheelementsfromonekindofcontainertoanotherdirectly,wecando

soindirectlybypassingapairofiterators(Section3.4,p.95).Whenweuseiterators,there

isnorequirementthattheconteiinertypesbeidentical.Theelementtypesinthecontainerscan

differaslongastheyarecompatible.Itmustbepossibletoconverttheelementwecopyinto

thetypeheldbythecontainerweareconstructing.

尽管不能宜接将•种容器内的元素复制给另•种容器,但系统允许通过传递,对迭代器(第3.4甘)间接

实现该实现该功能。使用迭代器时,不要求容器类型相同。容器内的元素类型也可以不相同,只要它们相互

兼容,能够将要复制的元素转换为所构建的新容器的元素类型,即可实现复制。

Theiteratorsdenotearangeofelementsthatwewanttocopy.Theseelementsareusedtoinitialize

theelementsofthenewcontainer.Theiteratorsmarkthefirstandonepastthelastelementto

becopied.Wecanusethisformofinitializationtocopyacontainerthatwecouldnotcopydirectly.

Moreimportantly,wecanuseittocopyonlyasubsequenceoftheothercontainer:

迭代器标记了要复制的元素范围,这些元素用于初始化新容器的元素。迭代器标记出要复制的第一个元素和

最后个元素。采用这种初始化形式可复制不能直接复制的容器。更重要的是,可以实现复制其他容器的一

个子序列:

//initializeslistwithcopyofeachelementofsvec

list<string>slist(svec.beginO,svec.end());

//findmidpointinthevector

vector<string>::iteratormid=svec.beginO+svec.size()/2;

//initializefrontwithfirsthalfofsvec:Theelementsuptobutnotincluding*mid

deque<string>front(svec.begin(),mid);

//initializebackwithsecondhalfofsvec:Theelements*midthroughendofsvec

deque<string>back(mid,svec.end());

Recallthatpointersareiterators,soitshouldnotbesurprisingthatwecaninitializeacontainer

fromapairofpointersintoabuilt-inarray:

回顾一下指针,我们知道指针就是迭代器,因此允许通过使用内置数组中的一对指针初始化容器也就不奇怪

了:

char*words[]={"stately”,〃plump〃,〃buck〃,“mulligan"};

//calculatehowmanyelementsinwords

size_twords_size=sizeof(words)/sizeof(char*);

//useentirearraytoinitializewords2

list<string>words2(words,words+words_size);

Hereweusesizeof(Section5.8,p.167)tocalculatethesizeofthearray.Weaddthatsizeto

apointertothefirstelementtogetapointertoalocationonepasttheendofthearray.The

initializersforwords2areapointertothefirstelementinwordsandasecondpointeronepast

thelastelementinthatarray.Thesecondpointerservesasastoppingcondition;thelocation

itaddressesisnotincludedintheelementstobecopied.

这里,使用sizeof(5.8节)计算数组的长度。将数组长度加到指向第一个元素的指针上就可以得到指向

超出数组末端的下一位置的指针。通过指向第一个元素的指针words和指向数组中最后•个元素的下•位

置的指针,实现了words2的初始化。其中第二个指针提供停止复制的条件,其所指向的位置上存放的元素

并没有复制。

AllocatingandInitializingaSpecifiedNumberofElements

分配和初始化指定数目的元素

Whencreatingasequentialcontainer,wemayspecifyanexplicitsizeandan(optional)initializer

tousefortheelements.Thesizecanbeeitheraconstantornon-constantexpression.Theelement

initializermustbeavalidvaluethatcanbeusedtoinitializeanobjectoftheelementtype:

创建顺序容器时,可显式指定容器大小和•个(可选的)元素初始化式。容器大小可以是常量或非常量表达

式,元素初始化则必须是可用于初始化其元素类型的对象的值:

constlist<int>::size_typelistsize=64;

list<string>slist(list_size,〃eh?〃);//64strings,eachiseh?

Thiscodeinitializesslisttohave64elements,eachwiththevalueeh?.

这段代码表示slist含有64个元素,每个元素都被初始化为“eh?”字符串。

Asanalternativetospecifyingthenumberofelementsandanelementinitializer,wecanalso

specifyonlythesize:

创建容器时,除了指定元素个数,还可选择是否提供元素初始化式。我们也可以只指定容器大小:

list<int>ilist(list_size);//64elements,eachinitializedto0

//svechasasmanyelementsasthereturnvaluefromget_word_count

externunsignedgetwordcount(conststring&fi1ename);

vector<string>svec(getwordcounl("Chimera"));

Whenwedonotsupplyanelementinitializer,thelibrarygeneratesavalue^initialized(Section

3.3.1,p.92)oneforus.Tousethisformofinitialization,theelementtypemusteitherbea

built-inorcompoundtypeorbeaclasstypethathasadefaultconstructor.Iftheelementtype

doesnothaveadefaultconstructor,thenanexplicitelementinitializermustbespecified.

不提供元素初始化式时,标准库将为该容器实现值初始化(3.3.l&nbps;jn。采用这种类型的初始化,元

素类型必须是内置或复合类型,或者是提供了默认构造函数的类类型。如果元素类型没有默认构造函数,则

必须显式指定其元素初始化式。

Theconstructorsthattakeasizearevalidonlyforsequentialcontainers;they

arenotsupportedfortheassociativecontainers,

接受容器大小做形参的构造函数只适用于顺序容器,而关联容器不支持这种初始化。

ExercisesSection9.1.1

ExerciseExplainthefollowinginitializations.Indicateifanyareinerror,and

9.1:ifso,why,

解释下列初始化,指出哪些是错误的,为什么?

intia[7]={0,1,172,3,5,8};

stringsa[6]={

“ForiSumter","Manassas","Perryville”,

“Vicksburg","Meridian","Chancellorsvilie*};

(a)vector<string>svec(sa,sa+6);

(b)list<int>ilist(ia+4,ia+6);

(c)vector<int>ivec(ia,ia+8);

(d)list<string>siist(sa+6,sa);

ExerciseShowanexampleofeachofthefourwaystocreateandinitializeavector.

9.2:Explainwhatvalueseachvectorcontains.

创建和初始化一个vector对象有4种方式,为每种方式提供一个例子,并解

释每个例子生成的vector对象包含什么值。

ExerciseExplainthedifferencesbetweentheconstructorthattakesacontainer

9.3:tocopyandtheconstructorthattakestwoiterators.

解释夏制容器对象的构造函数和使用两个迭代器的构造函数之间的差别。

9.1.2.ConstraintsonTypesthataContainerCanHold

9.1.2.容器内元素的类型约束

Whilemosttypescanbeusedastheelementtypeofacontainer,therearetwoconstraintsthat

elementtypesmustmeet:

C++语言中,大多数类型都可用作容器的元素类型。容器元素类型必须满足以下两个约束:

•Theelementtypemustsupportassignment.

元素类型必须支持赋值运算。

•Wemustbeabletocopyobjectsoftheelementtype.

元素类型的对象必须可以复制。

Thereareadditionalconstraintsonthetypesusedasthekeyinanassociativecontainer,which

we'11coverinChapter10.

此外,关联容器的键类型还需满足其他的约束,我们将在第十章介绍相关内容。

Mosttypesmeettheseminimalelementtyperequirements.Allofthebuilt-inorcompoundtypes,

withtheexceptionofreferences,canbeusedastheelementtype.Referencesdonotsupport

assignmentinitsordinarymeaning,sowecannothavecontainersofreferences.

大多数类型满足上述最低限度的元素类型要求。除了引用类型外,所有内置或复合类型都可用做元素类型。

引用不支持一般意义的赋值运算,因此没有元素是引用类型的容器。

Withtheexceptionofthe10librarytypes(andtheautoptrtype,whichwecoverinSection17.1.9

(p.702)),allthelibrarytypesarevalidcontainerelementtypes.Inparticular,containers

themselvessatisfytheserequirements.Wecandefinecontainerswithelementsthatarethemselves

containers.OurSales_itemtypealsosatisifestheserequirements.

除输入输出(10)标准库类型(以及第17.1.9节介绍的auto_ptr类型)之外,所有其他标准库类型都是

有效的容器元素类型。特别地,容器本身也满足上述要求,因应,可以定义元素本身就是容器类型的容器。

Sales_item类型也满足上述要求。

The10librarytypesdonotsupportcopyorassignment.Therefore,wecannothaveacontainerthat

holdsobjectsofthe10types.

10库类型不支持复制或赋值。因此,不能创建存放10类型对象的容器。

ContainerOperationsMayImposeAdditionalRequirements

容器操作的特殊要求

Therequirementtosupportcopyandassignmentistheminimalrequirementonelementtypes.In

addition,somecontaineroperationsimposeadditionalrequirementsontheelementtype.Ifthe

elementtypedoesn'tsupporttheadditionalrequirement,thenwecannotperformthatoperation:

Wecandefineacontainerofthattypebutmaynotusethatparticularoperation.

支持复制和赋值功能是容器元素类型的最低要求。此外,一些容器操作对元素类型还有特殊要求。如果元素

类型不支持这些特殊要求,则相关的容器操作就不能执行:我们可以定义该类型的容器,但不能使用某些特

定的操作。

Oneexampleofanoperationthatimposesatypeconstraintistheconstructorsthattakeasingle

initializerthatspecifiesthesizeofthecontainer.Ifourcontainerholdsobjectsofaclass

type,thenwecanusethisconstructoronlyiftheelementtypehasadefaultconstructor.Most

typesdohaveadefaultconstructor,althoughtherearesomeclassesthatdonot.Asanexample,

assumethatFooisaclassthatdoesnotdefineadefaultconstructorbutthatdoeshaveaconstructor

thattakesanintargument.Now,considerthefollowingdeclarations:

其中•种需外加类型要求的容器操作是指定容器大小并提供单个初始化式的构造函数。如果容器存储类类型

的对象,那么只有当其元素类型提供默认构造函数时,容器才能使用这种构造函数。尽管有一些类没有提供

默认构造函数,但大多数类类型都会有。例如,假设类Foo没有默认构造函数,但提供了需要•个int型

形参的构造函数。现在,考虑下面的声明:

vector<Foo>empty;//ok:noneedforelementdefaultconstructor

vector<Foo>bad(10);//error:nodefaultconstructorforFoo

vector<Foo>ok(10,1);//ok:eachelementinitializedto1

WecandefineanemptycontainertoholdFooobjects,butwecandefineoneofagivensizeonly

ifwealsospecifyaninitializerforeachelement.

我们定义一个存放Foo类型对象的空容器,但是,只有在同时指定每个元素的初始化式时,才能使用给定

容器大小的构造函数来创建同类型的容器对象。

Aswedescribethecontaineroperations,we'11notetheconstraints,ifany,thateachcontainer

operationplacesontheelementtype.

在描述容器操作时,我们应该留意(如果有的话)每个操作对元素类型的约束。

ContainersofContainers

容器的容器

Becausethecontainersmeettheconstraintsonelementtypes,wecandefineacontainerwhose

elementtypeisitselfacontainertype.Forexample,wemightdefinelinesasavectorwhose

elementsareavectorofstrings:

因为容器受容器元素类型的约束,所以可定义元素是容器类型的容器。例如,可以定义vector类型的容器

lines,其元素为string类型的vector对象:

//notespacing:use〃〉>〃not〃>〉〃whenspecifyingacontainerelementtype

vector<vector<string>>lines;//vectorofvectors

Notethespacingusedwhenspecifyingacontainerelementtypeasacontainer:

注意,在指定容器元素为容器类型时,必须如下使用空格:

vector<vector<string>>lines;//ok:spacerequiredbetweenclose>

vector<vector<string>>lines;//error:>>treatedasshiftoperator

Wemustseparatethetwoclosing>symbolswithaspacetoindicatethatthese

twocharactersrepresenttwosymbols.Withoutthespace,>>istreatedasasingle

symbol,therightshiftoperator,andresultsinacompile-timeerror.必须用

空格隔开两个相邻的>符号,以示这是两个分开的符号,否则,系统会认为»是单

个符号,为右移操作符,并导致编译时错误。

ExercisesSection9.1.2

ExerciseDefinealistthatholdselementsthataredequesthatholdints.

9.4:

定义一个list对象来存储deque对象里的元素,该deque对象存放int型

兀素。

ExerciseWhycanwenothavecontainersthatholdiostreatnobjects?

9.5:

为什么我们不可以使用容器来存储iostream对象?

ExerciseGivenaclasstypenamedFoothatdoesnotdefineadefaultconstructor

9.6:butdoesdefineaconstructorthattakesintvalues,definealistofFoo

thatholds10elements.

假设有个名为Foo的类,这个类没有定义默认构造函数,但提供了需要个

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论