- 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
- 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载。
- 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
- 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
- 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们。
- 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
- 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
几乎每个人都会使用std::vector,这是个好现象。不过遗憾的是,许多人都误解了它的语义,结果无意间以奇怪和危险的方式使用它。本条款中阐述的哪些问题会出现在你目前的程序中呢?
JG问题
1. 下面的代码中,注释A跟注释B所示的两行代码有何区别?
void f(vectorint v) {
?v[0];?????? // A
?v.at(0);? ??// B
}
Guru问题
2. 考虑如下的代码:
vectorint v;
?
v.reserve(2);
assert(v.capacity() == 2);
v[0] = 1;
v[1] = 2;
for(vectorint::iterator i = v.begin(); i v.end(); i++) {
?cout *i endl;
}
?
cout v[0];
v.reserve(100);
assert(v.capacity() == 100);
cout v[0];
?
v[2] = 3;
v[3] = 4;
// 厖
v[99] = 100;
for(vectorint::iterator i = v.begin(); i v.end(); i++) {
?cout *i endl;
}
请从代码的风格和正确性方面对这段代码做出评价。
解决方案
访问vector的元素
1. 下面的代码中,注释A跟注释B所示的两行代码有何区别?
// 示例1-1: [] vs. at
//
void f(vectorint v) {
?v[0];??? ????? // A
?v.at(0); ?????? // B
}
在示例1-1中,如果v非空,A行跟B行就没有任何区别;如果v为空,B行一定会抛出一个std::out_of_range异常,至于A行的行为,标准未加任何说明。
有两种途径可以访问vector内的元素。其一,使用vectorT::at。该成员函数会进行下标越界检查以确保当前vector中的确包含了需要的元素。试图在一个目前只包含10个元素的vector中访问第100个元素是毫无意义的,这样做会导致抛出一个std::out_of_range异常。
其二,我们也可以使用vectorT::operator[],C++98标准说vectorT::operator可以、但不一定要进行下标越界检查。实际上,标准对operator[]是否需要进行下标越界检查只字未提,不过标准同样也没有说它是否应该带有异常规格声明。因此,标准库实现方可以自由选择是否为operator[]加上下标越界检查功能。如果使用operator[]访问一个不在vector中的元素,你可就得自己承担后果了,标准对这种情况下会发生什么事情没有做任何担保(尽管你使用的标准库实现的文档可能做了某些保证)——你的程序可能会立即崩溃,对operator[]的调用也许会引发一个异常,甚至也可能看似无恙,不过会偶尔或神秘地出问题。
既然下标越界检查帮助我们避免了许多常见问题,那为什么标准不要求operator[]实施下标越界检查呢?简短的答案是效率。总是强制下标越界检查会增加所有程序的性能开销(虽然不大),即使有些程序根本不会越界访问。有一句名言反映了C++的这一精神:一般说来,不应该为不使用的东西付出代价(或开销)。所以,标准并不强制operator[]进行越界检查。况且我们还有另一个理由要求operator[]具有高效性:设计vector是用来替代内置数组的,因此其效率应该与内置数组一样,内置数组在下标索引时是不进行越界检查的。如果你需要下标越界检查,可以使用at。
调整vector的大小
现在让我们来看示例1-2,该示例对vectorint进行了简单操作。
2. 考虑如下的代码:
// 示例1-2: vector的一些函数
//
vectorint v;
v.reserve(2);
assert(v.capacity() == 2);
这里的断言存在两个问题,一个是实质性的,另一个则是风格上的。
首先实质性问题是,这里的断言可能会失败。为什么?因为上一行代码中对reserve的调用将保证vector的容量至少为2,然而它也可能大于2。事实上这种可能性是很大的,因为vector的大小必须呈指数速度上升,因而vector的典型实现可能会选择总是按指数边界来增大其内部缓冲区,即使是通过reserve来申请特定大小的时候。因此,上面代码中的断言条件表达式应该使用=,而不是==,如下所示:
assert(v.capacity() = 2);
其次,风格上的问题是,该断言(即使是改正后的版本)是多余的。为什么?因为标准已经保证了这里所断言的内容。所以再将它明确地写出来只会带来不必要的混乱。这样做毫无意义,除
您可能关注的文档
最近下载
- 紧密连接蛋白occludin、ZO-1在溃疡性结肠炎中的表达及其临床意义.pdf VIP
- 广东省科技计划项目申报书模板-申报书.PDF VIP
- 【黑里寨镇A小区建设工程项目施工组织设计国内外文献综述3300字】.docx VIP
- 神经外科俯卧位手术的常见并发症及护理对策.docx VIP
- 精神科护理警示教育心得体会范文.docx
- SEL-751A_美国SEL公司751A中文版说明书.PDF VIP
- 卫星气象学课件:第九章 由卫星资料定量估算气象参数.ppt VIP
- (可直接打印) 100以内加减法竖式计算2025题 .pdf VIP
- 体检结果异常分析.xlsx VIP
- 食品卫生基础知识课件.pptx VIP
原创力文档


文档评论(0)