<Effective STL>笔记--容器

C++ STL之stack栈容器 STL:1)标准模版库,提供了通用的模版库和函数。如:向量、链表、队列、栈。2)核心组建包括:容器(Containers)、算法(Algorithms)、迭代器(Iterators)。Stack栈容器:1)容器适配器,遵循先进后出(FILO)数据结构。2)头文件:#include <stack>3)常用函数:empty:判断堆栈元素是否为空,true表示栈元素为空;pop:移除栈顶元素... 阅读详情

1 容器
~~~~~~~

1.1 仔细选择容器
=================
   1. C++中的容器回顾
      * 标准STL序列容器:
        vector、string、deque和list。
      * 标准STL关联容器:
        set、multiset、map和multimap。
      * 非标准序列容器:
        slist(slist是一个单向链表)和rope(rope本质上是一个重型字符串)
      * 非标准关联容器:
        hash_set、hash_multiset、hash_map和hash_multimap。
      * 几种标准非STL容器:
        数组、bitset、valarray、stack、queue和priority_queue。
   2. 连续内容容器和基于节点的容器的区别
      * 连续内容容器(也叫基于数组的容器)在一个或多个(动态分配)的内存块中保持它们的元素.
        连续内存容器包括vector,string和depue
      * 基于节点的容器在每个内存块(动态分配)中只保存一个元素。
        基于节点的容器包括list,slist,所有的标准关联容器(一般实现是用平衡树实现的)和非标准的散列容器(不同的基于节点的实现)
   3. 选用何种容器的标准
      * 你关心元素在容器中的顺序吗?
        如果不,散列容器就是可行的选择。否则,你要避免使用散列容器。
      * 你需要哪一类迭代器?
        如果必须是随机访问迭代器,在技术上你就只能限于vector、deque和string,但你也可能会考虑rope。
        如果需要双向迭代器,你就用不了slist和散列容器的一般实现
      * 容器中的数据的内存布局需要兼容C吗?
        如果是,你就只能用vector
      * 你介意如果容器的底层使用了引用计数吗?
        如果是,你就得避开string,因为很多string的实现是用引用计数。你也不能用rope,因为权威的rope实现是基于引用计数的。
        于是你得重新审核你的string,你可以考虑使用vector<char>。
      * 你需要插入和删除的事务性语义吗?也就是说,你需要有可靠地回退插入和删除的能力吗?
        如果是,你就需要使用基于节点的容器。如果你需要多元素插入(比如,以范围的方式)的事务性语义,你就应该选择list,因为list是唯一提供多元素插入事务性语义的标准容器。
      * 你要把迭代器、指针和引用的失效次数减到最少吗?
        如果是,你就应该使用基于节点的容器,因为在这些容器上进行插入和删除不会使迭代器、指针和引用失效(除非它们指向你删除的元素)。
        一般来说,在连续内存容器上插入和删除会使所有指向容器的迭代器、指针和引用失效。
      * 你需要具有有以下特性的序列容器吗:1)可以使用随机访问迭代器;2)只要没有删除而且插入只发生在容器结尾,指针和引用的数据就不会失效?
        这个一个非常特殊的情况,但如果你遇到这种情况,deque就是你梦想的容器。
        有趣的是,当插入只在容器结尾时,deque的迭代器也可能会失效,deque是唯一一个“在迭代器失效时不会使它的指针和引用失效”的标准STL容器。

1.2 小心写"与容器类型无关"的代码
=================================
   1. 写既要和序列容器又要和关联容器一起工作的代码并没有什么意义.
      因为很多成员函数只存在于其中一类容器中.不同的容器是不同的,而且它们的优点和缺点有重大不同。它们并不被设计成可互换的,而且你做不了什么包装的工作。
   2. nultimap不存在operator[]
   3. 若存在改变容器类型的可能.
      可以使用typedef封装容器类型.
      也可以新建一个类,在类中定义一个隐藏的容器对象.通过类的接口限制容器特殊信息可见性的数量

1.3 使容器里对象的拷贝操作轻量且正确
=====================================
   1. 当你从容器中获取一个对象时,你所得到的对象不是容器里的那个对象.而是拷贝.
      当你向容器中添加一个对象,进入容器的是你指定的对象的拷贝.
      拷进去,拷出来。这就是STL的方式.
   2. 在容器中插入删除操作或使用排序算法等会移动容器元素的操作,也会引发元素的拷贝.
   3. 把一个派生类对象插入基类对象的容器几乎总是错的,因为对象在拷贝入容器时会产生分隔

1.4 用empty来代替检查size()是否为0
===================================
   1. 你应该首选empty的构造,而且理由很简单:对于所有的标准容器,empty是一个常数时间的操作,但对于一些list实现,size花费线性时间。

1.5 尽量使用区间成员函数来代替它们的单元素兄弟
===============================================
   1. 尽量使用区间成员函数代替它们的单元素兄弟的理由。
      * 一般来说使用区间成员函数可以输入更少的代码。
      * 区间成员函数会导致代码更清晰更直接了当。
      * 当处理标准序列容器时,应用单元素成员函数比完成同样目的的区间成员函数需要更多地内存分配,更频繁地拷贝对象,而且/或者造成多余操作.
        1) 第一种税在于没有必要的函数调用。
           把numValues个元素插入v,每次一个,自然会花费你numValues次调用insert。
           而区间成员函数只需一次调用开销
        2) 无效率地把v中的现有元素移动到它们最终插入后的位置的开销。
           每次调用insert来增加一个新元素到v,插入点以上的每个元素都必须向上移动一次来为新元素腾出空间。这就移动了numValues次.
           而区间成员函数只需一次移动开销
        3) 插入数据时可会会有内存分配的开销.
           多次插入数据可能会有多次内存分配的开销.
           区间分配使得只需要分配一次内存
   2. string和vector在元素数目减少时,不会自动缩减内存分配

1.6 警惕C++最令人恼怒的解析
============================
   1. 几乎任何东西都可能被分析成函数声明.
  //假设你有一个int的文件,你想要把那些int拷贝到一个list中。这看起来像是一个合理的方式:
 

 
  1. ifstream dataFile("ints.dat"); 
  2.   list<int> data(istream_iterator<int>(dataFile),   // 警告!这完成的并不 
  3.   istream_iterator<int>());         // 是像你想象的那样 



      事实上,这声明了一个函数data,它的返回类型是list<int>。这个函数data带有两个参数:
      第一个参数叫做dataFile。它的类型是istream_iterator<int>。dataFile左右的括号是多余的而且被忽略。
      第二个参数没有名字。它的类型是指向一个没有参数而且返回istream_iterator<int>的函数的指针。
      正确的做法是
 

 
  1. ifstream dataFile("ints.dat"); 
  2. istream_iterator<int> dataBegin(dataFile); 
  3. istream_iterator<int> dataEnd; 
  4. list<int> data(dataBegin, dataEnd); 


1.7 当使用new的指针的容器时,记得在销毁容器后delete那些指针
===========================================================
   1. auto_ptr在C++标准中时禁止插入容器的,虽然有些编译器允许容器中插入auto_ptr,但这是不可移植的.
   2. 由于auto_ptr复制方面的特性,在调用容器的方法后,可能会使原元素设为NULL

1.8 从容器中删除元素时,仔细选择不同的策略
==========================================
   1. 去除一个容器中有特定值的所有对象:
      * 如果容器是vector、string或deque,使用erase-remove惯用法。
 

 
  1. c.erase(remove(c.begin(), c.end(), 1963),       // 当c是vector、string 
  2.         c.end());                               // 或deque时, 
  3.                                         // erase-remove惯用法 
  4.                                         // 是去除特定值的元素 
  5.                                         // 的最佳方法 



      * 如果容器是list,使用list::remove。
      * 如果容器是标准关联容器,使用它的erase成员函数。
   2. 去除一个容器中满足一个特定判定式的所有对象:
      * 如果容器是vector、string或deque,使用erase-remove_if惯用法。
      * 如果容器是list,使用list::remove_if。
      * 如果容器是标准关联容器,使用remove_copy_if和swap,或写一个循环来遍历容器元素,当你把迭代器传给erase时记得后置递增它。
        要注意,关联容器中删除一个元素后,指向该元素的iterator会失效,故采用后置递增.在iterator被删除前递增,并将递增前的值传给erase
   3. 在循环内做某些事情(除了删除对象之外):
      * 如果容器是标准序列容器,写一个循环来遍历容器元素,每当调用erase时记得都用它的返回值更新你的迭代器。
        要注意,序列容器中删除一个元素后,指向该元素的iterator及之后的所有迭代器都会失效,但erase会返回一个iterator,指向被删除元素的后一个元素.
      * 如果容器是标准关联容器,写一个循环来遍历容器元素,当你把迭代器传给erase时记得后置递增它。

1.9 注意allocator的协定和约束
==============================
   看不懂

1.10 理解自定义allocator的正确用法
===================================
   看不懂

1.11 对STL容器的线程安全性的期待现实一点
=========================================
   1. STL容器对多线程的支持为
      * 多个读取者是安全的:
        多线程可能同时读取一个容器的内容,这将正确地执行。当然,在读取时不能有任何写入者操作这个容器。
      * 对不同容器的多个写入者是安全的:
        多线程可以同时写不同的容器。
 

本文出自 “暗日” 博客,请务必保留此出处http://darksun.blog.51cto.com/3874064/1162469

Purify使用指南 1. 简介2. 安装2.1. 安装license2.2. 安装Purify3. 使用3.1. 查看帮助3.2. 使用步骤   ATTACH3.3. 查看BUG   ATTACH3.4. 定位BUG在源代码中的位置   ATTACH3.5. 查找泄漏的内存   ATTACH3.6. 修改BUG   ATTACH3.7. 隐藏消息   ATTACH4. 保存/载入结果4.1. 保存结果4.2. 载入结 阅读详情

相关推荐

RL调参侠之BipedalWalker BipedalWalkerHardcore SAC

前几天用PPO训练了个很一般的agent: RL调参侠之BipedalWalker PPO 我看SpinningUp上面说PPO和SAC是两个领域里各自的State_of_the_art的方法,所以就打算跑SAC试试看,之前因为Open AI Five的原因,一直感觉PPO很牛掰,实际上现在很多自动驾驶的算法也是用PPO在跑,毕竟有一个“必定能够提升期望”的理论保证在这里,我理解这对做项目很大的诱惑。 不过我跑出来的结果明显是SAC更好。 调参侠时间 策略熵的权重alpha用的0.2,我一开始没有看SAC的

weixin_48370148的博客 2101

Linux 64位 CentOS下安装 Docker 容器,启动、停止

一、Docker简介 Docker 提供了一个可以运行你的应用程序的封套(envelope),或者说容器,是轻量级的“容器引擎+映像仓库”,在LXC(linux轻量级容器)的基础上构建,可以运行任何应用程序。 Docker 扩展了 Linux 容器(Linux Containers),或着说 LXC,通过一个高层次的 API 为进程单独提供了一个轻量级的虚拟环境。Docker 利用了 LXC,...

weixin_30415113的博客 476

信道估计之MMSE算法

信道估计之MMSE算法前言MMSE估计的原理总结 前言        前篇分析了LS信道估计算法,也说明了由于没有考虑SNR的影响,所以LS算法不适合在低信噪比的情况下使用。本篇来学习信道估计的另外一种常用的算法–MMSE。        为什么说LS没有考虑噪声大小的情况呢,因为LS算法使用的是实际观测量与估计观测量的误差,这并不能精确的代表估计量的真值与估计值的误

大白的博客 2万+

GT-Grid的实例

下面是GT-Grid的详细使用:  1.首先需要在页面定义gt-grid展示容器,一般都是用标签来实现:       2.需要导入gt-grid的js文件和样式: /style/ui_component/gt-grid/gt_grid.css" /> /sty

xilangyuyun的专栏 3474

python:numpy分享(保姆级教程)

创建数组:array和ndarray、rand()、randn()、arange()、randint()、uniform()astype()基础函数:ceil()、floor()、rint()、argmax()、argmin()、cumsum()、cumprod()numpy 是数据分析必不可少的第三方库,具有高性能的特点,多用于做数组分析。内置函数:ceil()、floor()、rint()主要用于数组计算,支持多维数组。array和ndarray。比较函数:all、any。去重函数:unique。

sulin123123的博客 1730

VC Spyglass实战指南:从零开始掌握CDC约束配置与调试

本文详细介绍了如何使用VC Spyglass进行CDC约束配置与调试,从基础环境搭建到典型CDC问题调试实战,帮助开发者快速掌握跨时钟域验证技术。通过TCL脚本和SDC约束的深度解析,提升CDC验证效率,避免常见设计风险。

weixin_26757925的博客 297

<Effective STL>笔记--容器

1 容器 ~~~~~~~ 1.1 仔细选择容器 ================= 1. C++中的容器回顾 * 标准STL序列容器: vector、string、deque和list。 * 标准STL关联容器: set、multiset、map和multimap。 * 非标...

weixin_34242658的博客 158

ESP32搭配FT6236触摸屏:从芯片手册到完整I2C驱动代码的保姆级解析

本文详细解析了ESP32搭配FT6236触摸屏的I2C驱动开发过程,从芯片手册解读到完整代码实现。通过硬件架构分析、寄存器配置、I2C通信封装及触摸数据处理等步骤,提供了一套完整的驱动解决方案,帮助开发者快速掌握ESP32与触摸屏的交互技术。

weixin_29174385的博客 294

GTK+2.0 中的容器控件与布局技巧

 学习图形界面编程,要过的第一关就是熟悉控件的使用,快速掌握控件的使用和布局技巧是初学者最为迫切的要求,本文向有意在LINUX下用GTK+2.0开发图形界面应用程序的初学者朋友们指出这一途径简介GTK+(GIMP TOOLKIT),是一个跨平台的图形界面(GUI)开发工具,是目前LINUX操作系统中较常用的图形界面开发工具之一,它采用一种非常有特色的面向对象的C语言开发框架(C Framewo

lastking的专栏 2792

ARM Linux工控板+C# .NET Core:倍福ADS协议轻量化工业控制(附跨平台部署代码)

某自动化设备厂的倍福PLC控制系统曾依赖传统x86工控机:单台设备需配备1台Intel i5工控机(成本约8000元),功耗30W+,且Windows系统稳定性受工业环境干扰(如电磁辐射导致蓝屏)。更棘手的是,设备需部署在产线边缘(空间狭小),x86工控机的体积(4U机架)和散热需求(风扇噪音)难以适配;而多设备部署时,高硬件成本和高功耗导致年运维成本超20万元。

这里只有干货:从 Modbus 通信到 MES 对接,从 YOLO 训练到工控机部署,带你搞定工业软件开发全流程。 954

32、高光谱遥感技术在军事领域的应用解析

高光谱遥感技术凭借其高分辨率和精细光谱分析能力,在军事领域广泛应用于战场详细侦察、伪装目标识别及目标实际温度与发射率的检测,显著提升了目标识别精度和作战支持能力。同时,该技术在内陆水体成分反演、海洋环境监测和农业管理等领域也展现出巨大潜力。尽管面临数据量大、处理复杂、技术融合不足和仪器性能限制等挑战,未来通过人工智能融合、高效算法研发和先进仪器开发,高光谱遥感技术将在多领域实现更深入应用与发展。

blue的专栏 231

STL几种容器的简单理解

本文按照自己的理解,对C++ STL(标准模板库)中的常见容器,做简单记录 容器简单分类:队列型、表型 一. 队列 std::vector 特性:连续空间的队列; 优点:查找快,按下标查找;算法复杂度 O(1) 缺点:插入删除慢;因为头插-push_front和插入-insert,需要移动指定节点后面的所有元素; 算法复杂度 O(N)。尾插算法复杂度O(1) std::list ...

打破牢笼,未来无限可能 360

游戏大厂如何解析引擎技术

本文系统解析了游戏大厂如何评估和定制游戏引擎。游戏引擎作为游戏开发的核心基础,大厂会从性能、跨平台支持、渲染能力、网络模块等8个维度进行技术解析,通过文档查勘、源码阅读、Demo测试等7个步骤深度评估。解析后通常有三种决策:直接使用、深度定制或自研重构。文章以腾讯、网易、米哈游等为例,展示了不同厂商的引擎定制策略,并分析了技术解析面临的挑战和未来趋势。最终指出,体系化的引擎技术解析是打造高质量游戏的关键,需要持续的技术投入和团队协作。

本博客聚焦游戏开发技巧、创业实战心得及大学热门课程干货。这里既有技术深度,也有思维广度,无论你是开发者、创业者还是高校学子,都能在这里找到适合自己的成长之路! 535

&lt;Effective STL&gt;笔记--关联容器

3 关联容器 ~~~~~~~~~~~ 3.1 了解相等和等价的区别 =========================    1. find对“相同”的定义是相等,基于operator==。set::insert对“相同”的定义是等价,通常基于operator    2. 操作上来说,相等的概念是基于operator==的       等价是基于在一个有序区间中对象值的相对位置

暗日 437

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

&lt;Effective STL&gt;笔记--迭代器

4 迭代器 ~~~~~~~~~   现标准STL容器提供了四种不同的迭代器:   * iterator   * const_iterator   * reverse_iterator   * const_reverse_iterator 4.1 尽量用iterator代替const_iterator,reverse_iterator和const_reverse_iterator

暗日 406

TMS_WebGMaps_1.9.8.0_Full_Source

TMS_WebGMaps_1.9.8.0_Full_Source 全源码 delphi cbuilder

&lt;Effective STL&gt;笔记--算法

5 算法 ~~~~~~~ 5.1 确保目标区间足够大或者在算法执行时可以增加大小 ===================================================    1. 在算法中,要往Container中插入新数据,需要使用插入迭代器(比如,从back_inserter、front_inserter或inserter返回的迭代器之一)。    2. r

暗日 327

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

&lt;Effective STL&gt;笔记--vector和string

2 vector和string ~~~~~~~~~~~~~~~~~ 2.1 尽量使用vector和string来代替动态分配的数组 ===============================================    1. string可能使用了引用计数,这时在多线程环境下你可能发现避免分配和拷贝所节省下的时间都花费在后台并发控制上了.(string本身实现了并发控

暗日 412

GT中的一些基本概念

<br /> 一、如何建立Gtk+应用<br /><br />    1.基本概念<br /><br />    在Linux上开发GUI应用软件,我们通常利用Gtk+库。为了深入了解Gtk+的应用,我们首先要明确几个概念。<br /><br />    (1) 构件(widget)的概念<br /><br />    在Gtk+库里的窗口、选单和按钮等应用实体,我们称之为构件(widget)。构件具有面向对象的特征,其具体结构由Gtk+库定义,它对运用构件的程序员来说是透明的,除非你想创建自己的构件。在对

uunubt的专栏 780

Effective STL

Effective STL 导读 应该高效的过程却需要比你希望给它们的更多的时间和内存。是的,你知道怎么使用STL,但你不确定你在有效地使用它。 描述了常见的STL使用错误,而且向你演示怎么避开它们。那帮助你躲开闪资源漏、不可移植的代码和未定义的行为。 本书里的信息将使你成为一个更好的STL程序员,它将让你成为一个更高产的程序员。而且它将让你成为一个更愉快的程序员,使用STL很有趣,但是有效地使用...

勤学如春起之苗,不见其增,日有所长! 辍学如磨刀之石,不见其损,日有所亏! 446

操作Docker容器(1)创建容器

操作Docker容器(1) 创建容器 ​ 从现在开始,你会一点一点的慢慢忘掉臃肿的虚拟机,对容器的操作就像直接操作应用一样简单和快速。 ​ 本节主要讲解Docker容器的create,start,run,wait,和logs子命令。 1.新建容器 可以使用docker create 命令新建一个容器,例如: [h@h-81r7 ~]$ docker create -it ubuntu:latest 2d0ea8ca7f5d07647bb336d1ad25ddc73816ab15e8c4551d7c9a82d

gtdisscary的博客 2万+

GTK:容器布局之水平布局

参考链接: https://blog.youkuaiyun.com/tennysonsky/article/details/42741907 代码: #include &lt;gtk/gtk.h> #include &lt;stdio.h> int main(int argc, char **argv) { //初始化 gtk gtk_init(&argc, &argv);...

Linux 545

STL 通用容器分类--顺序性容器、关联式容器、容器适配器

通用容器的分类 STL 对定义的通用容器分三类:顺序性容器、关联式容器和容器适配器。 下表列出STL 定义的三类容器所包含的具体容器类: 顺序性容器 是一种各元素之间有顺序关系的线性表,是一种线性结构的可序群集。顺序性容器中的每个元素均有固定的位置,除非用删除或插入的操作改变这个位置。这个位置和元素本身无关,而和操作的时间和地点有关,顺序性容器不会根据元素的特点排序而是直接保存了元素操作时的逻辑...

qq_36559293的博客 871

容器优缺点

容器的优点 敏捷环境:容器技术最大的优点是创建容器实例比创建虚拟机示例快得多,容器轻量级的脚本可以从性能和大小方面减少开销。 高资源利用率与隔离,提高生产力:容器通过移除跨服务依赖和冲突提高了开发者的生产力。每个容器都可以看作是一个不同的微服务,因此可以独立升级,而不用担心同步。容器没有管理程序的额外开销,与底层共享操作系统,性能更加优良,系统负载更低,在同等条件下可以运行更多的应用实例,可以...

仰卧起坐式学习 1万+

cppcheck使用指南

cppcheck使用指南Table of Contents1 cppcheck简介2 cppcheck使用3 cppcheck与其他软件的整合3.1 与VisualStudio的配合3.2 与TortoiseSVN配合1 cppcheck简介cppcheck是一个静态代码检查工具,支持c/ c++代码;作为编译器的一种补充检查,cppcheck对产品的源代码执行严格的逻辑检查。执行的检查包括:自动

暗日 1万+

当用fopen读写打开文件时,请使用r+,而不是rw

C++标准中fopen函数的mode只有r,r+,w+,a,a+这几种类别,而没有rw这种类别. 如果尝试对用rw方式打开文件进行写操作,不同的编译器会有不同的处理方式.例如在linux下用gcc4.6.3把rw当成r来处理,会提示bad file descriptor在windows下用dev C++则只是将写文件函数返回失败,但是没有设置errno根据百度百科的说明,还有些编译器则能够把rw识

暗日 5081
上一篇: 《Effective C++第三版》读书笔记——定制new和delete
下一篇: &lt;Effective STL&gt;笔记--vector和string
darksun9972
博客等级 码龄19年 42粉丝 399原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值