读 "Effective STL" 笔记

 

C2@vector & string

 

reserve()与resize()的区别在于:reserve()仅仅会为你分配一段未经初始化的内存空间,容器内元素的个数也即容器的size()并不会改变,使用reserve()的初衷在于当容器的使用情况可预知时,提前调用reserve()预分配空间可避免reallocation所带来的沉重开销;resize()的行为是分配一段已初始化的空间,容器内元素的个数(Container.size()以及Container.end())随之改变,resize()的初衷在于一些基于assignment的STL算法只能对已经初始化完成的(也即constructor()已被调用的)内存空间施加操作。

 

std::string包含的成员可能会包括,

@size & @capacity;

@pointer & @allocator: 字符串的实际分配是经由Allocator通过动态分配实现的,allocator会作为具象实例存在于每个string中;

@reference count: 从节省空间的角度考虑,很多的库都会含有该成员。当需要使用某字符串例如”hello cplusplus”时,程序会动态分配一份,接下来所有使用该字符串的string仅仅通过@pointer指向该字符串,其被引用的个数记录在@reference count中,@reference count减为0时动态进行销毁。

基于这些成员可以得知,为什么sizeof(string)会出人意料的大。




C3@Associative Container

 

在STL中有两种“相等”:一种是algorithm::find()所定义的相等,基于operator==()实现;另一种则是std::set/map所定义的相等,基于operator<()实现。二者都用于查找,直观来看operator==()足够使用,而之所以operator<()会被使用在于set/map是有序的,从有序的容器中查找元素,基于operator<()的二分法能够提供远优于线性查找的性能。

 

当然,利用operator<()定义的“相等”可能会让人觉得过于繁琐 A == B <--> !operator<(A, B)&& !operator<(B, A),翻译一下就是A不小于B同时B不小于A。熟悉二分法的朋友或许会问,何不将operator==()与operator<()混在一起使用,毕竟二分法中是先判断”if(B == mid)”,当不等时才会引入”<”。问题在于这就需要operator==()和operator<()的定义保持一致性,考虑一个字符串的比较,如果operator==()假定大小写不敏感而operator<()假定大小写敏感,这个查找就会出现问题。换句话来讲,混合使用可能会引入定义的不一致进而导致程序出现问题。

 

最后,当容器中存储的是你声明的Class时,记得定义自己的operator==(), operator<()。

 

 

C4@Iterator

 

鉴于很多container的成员函数要求输入参数是iterator而将const_iterator拒之门外,所以在很多情况下const_iterator的使用者就必要为手里的const_iterator摘掉const的帽子。卸帽工具?第一反馈该是const_cast<>,不过让人略感意外的是…这直观的方式在多数情况下(string, vector除外)会难以通过编译。

 

问题的原因在于对大多数container(包括list, deque, set,multiset, map, multimap)而言,它们的iterator和const_iterator实现源于不同的类,通过const_cast<>完成不同class的转化,Bjarne的口味应该不会这么重。Scott给出的解决方案是引入advance()和distance():

std::advance ( iter ascontainer.begin(), 

                           std::distance<const_type>( container.begin(), const_target_iter )

 

至于前文提到的例外-- string和vector,const_cast<>是可以起作用的,原因在于这两个容器里pointer和iterator是等价的,即为

vector<T>::iterator等价于T*, 同时vector<T>::const_iterator等价于const T*。自然const_cast<>刚好够用。

 

 

 

 

源码来自:https://pan.quark.cn/s/41b9d28f0d6d 在信息技术领域中,jQuery作为一个广受欢迎的JavaScript框架,显著简化了诸多操作,包括对HTML文档的遍历、事件的管理、动画的设计以及Ajax通信等。 本篇文档将深入阐释如何运用jQuery达成一个图片自动播放的功能,这种效果常用于网站的轮播展示或幻灯片演示,有助于优化用户与页面的互动,使网页呈现更加动态的视觉体验。 为了有效实施这一功能,首先需掌握jQuery的核心操作。 通过$符号作为接口,jQuery能够迅速选取DOM组件,例如$("#id")用于选取具有特定ID的元素,而$(".class")则能选取所有应用了某类class的元素。 在选定元素之后,可以执行多种行为,诸如事件监听、样式的变更、内容的更新以及动画的制作等。 关于“一个基于jQuery的图片自动播放功能”,首要任务是准备一组图片素材,这些素材将被整合至一个容器元素之中。 例如,可以构建一个div元素,将其宽度设定为单张图片的尺寸,再借助CSS实现溢出内容的隐藏,从而构建出水平滚动的初始框架。 ```html<div id="slider"> <img src="image1.jpg" alt="Image 1"> <img src="image2.jpg" alt="Image 2"> <!-- 更多图片内容... --></div>```接着,需要编写jQuery脚本以实现图片的自动切换。 这通常涉及到定时器的运用,以设定周期性间隔自动更换当前显示的图片。 通过使用`.fadeOut()`和`.fadeIn()`方法,能够实现图片间的平滑过渡,增强视觉效果。 ```javascript$(document).re...
<think>首先,用户的问题是关于获取《Effective STL》的笔记或相关总结。用户说:“我想获取《Effective STL》的笔记或相关总结 请问Effective STL 笔记 总结”。这似乎是用户的核心需求。 现在,回顾系统级指令: - 所有行内数学表达式必须使用$...$格式。 - 独立公式使用$$...$$格式并单独成段。 - LaTeX语法正确。 - 使用中文回答。 - 生成相关问题。 - 回答中引用的段落末尾自然地添加引用标识,例如:[^1]。 用户可见层指令: - 回答结构清晰,帮助用户逐步解决问题。 - 尽量保证回答真实可靠。 参考站内引用:提供了几个引用,如[^1]、[^2]、[^3]、[^4],这些是关于《Effective STL》的内容。引用[^1]讨论了STL容器在添加元素时的行为,以及一个transform函数的错误用法。引用[^2]涉及reverse_iterator的base()成员函数。引用[^3]强调在std::advance中指定类型的重要性。引用[^4]简要比较了list和vector的特性。 用户的问题直接请求笔记或总结,所以我应该基于这些引用和我的知识来提供《Effective STL》的笔记总结。 《Effective STL》是Scott Meyers写的一本书,专注于如何高效使用C++标准模板库(STL)。它包含50条条款,涵盖容器、算法、迭代器等主题。 我的回答结构应该清晰: 1. **引言**:简要介绍《Effective STL》和它的重要性。 2. **关键点总结**:基于引用和常见知识,总结书中的主要教训。例如: - 容器选择和使用。 - 算法和迭代器的正确用法。 - 性能考虑。 引用中提到的点: - 引用[^1]:容器在添加元素时自动扩展,但迭代器使用错误会导致运行时错误。例如,transform函数中使用end()迭代器不正确。 - 引用[^2]:reverse_iterator的base()函数用法。 - 引用[^3]:在std::advance中指定类型以避免编译错误。 - 引用[^4]:list和vector的比较。 3. **生成相关问题**:在回答末尾添加相关问题,以帮助用户深入学习。 由于用户要求中文回答,我将全程使用中文。 确保没有数学表达式,因为STL主题不涉及数学,所以可能不需要LaTeX。但如果涉及任何数学,比如在算法复杂度中,我会使用$...$格式。不过,在这个上下文中,可能不需要。 现在,构建回答: - **开头**:直接回应用户需求,提供总结。 - **主体**:组织成几个部分,如容器、算法、迭代器等,总结关键点。自然地融入引用。 - **结尾**:添加相关问题。 最后,添加引用标识:[^1], [^2], [^3], [^4]在适当的地方。 相关问题示例: 1. 如何选择STL容器? 2. 什么是迭代器失效问题? 3. 如何优化STL算法的性能? 4. 《Effective STL》中的关键条款有哪些? 确保回答真实可靠:基于书的内容和引用。</think>### 《Effective STL笔记总结 《Effective STL》是Scott Meyers所著的经典C++书籍,专注于高效使用C++标准模板库(STL)。书中提供了50条实用条款,涵盖容器、算法、迭代器等核心主题。以下基于书中内容及相关引用,总结关键要点,帮助您快速掌握精髓。总结分为几个主要部分,确保结构清晰易懂。 #### 1. **容器选择与使用** - **容器类型比较**:STL容器(如`vector`、`list`)各有优缺点。`vector`支持随机访问(使用`[]`运算符),但插入/删除元素时可能触发重新分配内存;`list`基于链表实现,插入/删除高效(时间复杂度$O(1)$),但不支持随机访问,且提供特有成员函数如`sort()`、`reverse()`、`unique()`和`splice()`[^4]。 - **自动扩展机制**:容器在添加元素时(通过`insert`、`push_back`等)会自动扩展内存,但需注意迭代器失效问题。例如,添加元素后,原有迭代器可能失效,导致未定义行为[^1]。 - **性能陷阱**:避免在循环中频繁添加元素,因为这可能引起多次内存重分配。使用`reserve()`预分配内存可优化`vector`性能[^1][^4]。 #### 2. **算法与迭代器的正确用法** - **迭代器错误示例**:使用算法时,迭代器范围必须有效。常见错误如`transform`函数中传递无效迭代器: ```cpp vector<int> values; vector<int> results; transform(values.begin(), values.end(), results.end(), transmogrify); // 错误:results.end() 不是有效插入点 ``` 应改用`back_inserter(results)`确保安全插入[^1]。 - **迭代器类型转换**:当混合`iterator`和`const_iterator`时,需显式指定类型以避免编译错误。例如,使用`std::advance`时: ```cpp std::advance(i, std::distance<const_iterator>(i, ci)); // 必须指定<const_iterator> ``` 这是因为`std::distance`要求迭代器类型一致,编译器无法自动推导[^3][^2]。 - **反向迭代器处理**:`reverse_iterator`的`base()`成员函数可将反向迭代器转换为正向迭代器,但需注意偏移问题: ```cpp std::vector<int>::reverse_iterator ri = std::find(v.rbegin(), v.rend(), 7); std::vector<int>::iterator i(ri.base()); // 转换后,i 指向 ri 的下一个元素 ``` 这在删除或插入操作时特别有用[^2]。 #### 3. **性能优化与最佳实践** - **算法选择**:优先使用STL内置算法(如`sort()`、`find()`),而非手动循环,以提升效率。但注意,某些容器(如`list`)有专属算法(如`list::sort()`),可能比通用算法更高效[^4]。 - **避免不必要的拷贝**:使用`emplace`系列函数(如`emplace_back()`)直接构造对象,减少临时对象创建的开销。 - **内存管理**:对于`vector`,在已知大小时预先调用`reserve()`,避免多次扩容(扩容时间复杂度平均为$O(n)$)。 - **通用规则**:书中强调“了解你的容器”,例如,`vector`适合随机访问,`list`适合频繁插入/删除;同时,遵循“迭代器失效规则”,确保操作安全[^1][^4]。 #### 4. **关键条款精华** - **条款1-10**:关注容器选择,如“使用`vector`和`string`优先于数组”。 - **条款11-20**:强调迭代器安全,如“避免使用`vector<bool>`,因其非标准容器”。 - **条款21-30**:算法优化,如“使用`remove`-`erase`惯用法删除元素”。 - **条款31-50**:高级主题,如“理解`reverse_iterator`和`base()`的关系”[^2][^3]。 本书核心思想是:STL虽强大,但误用易导致性能下降或错误。通过以上总结,您可快速应用这些原则提升代码质量。如需更详细内容,建议阅原书或参考完整笔记[^1][^2][^3][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值