条目八《永不建立auto_ptr的容器》
条目八《永不建立auto_ptr的容器》
重要的事说三次,永不建立auto_ptr的容器,永不建立auto_ptr的容器,永不建立auto_ptr的容器!!!
为什么?
实质是auto_ptr指针在转移时把原本的指针置为NULL,然而在STL容器中的一些操作是包含数据转移操作的。
比如排序sort(),在STL中,容器的sort的底层是基于多种排序算法的,其中的快排更是最重要的一种。快排的核心是每次递归选出一个基准值,然后把数据分为大小于基准值两部分,直至整个数据排列完成。
假如是auto_ptr容器,在每次递归的时候,基准值会转移为NULL,并且这个基准值局部变量在当前递归结束时会被销毁,因此会发生整个快排下来,整个数据会有几个数值是缺少的和为NULL的,这些数据都是每次递归选出来的基准值。
请看stl源码:
bool widgetAPCompare(const auto_ptr<Widget>& lhs, const auto_ptr<Widget>& rhs)
{
return *lhs < *rhs;
}
vector<auto_ptr<Widget> > widgets;
sort(widgets.begin(), widgets.end(), widgetAPCompare);
这是一个vector的sort例子。
template<class RandomAccessIterator, class Compare>
void sort(RandomAccessIterator first, RandomAccessIterator last, Compare comp)
{
typedef typename iterator_traits<RandomAccessIterator>::value_type ElementType; //先忽略此句,这里主要是获取数据的类型
RandomAccessIterator i; //i指向基准值
...
ElementType pivotValue(*i); //把基准值复制到局部临时变量中
...
}
这里的重点的这一句ElementType pivotValue(*i);,解释直接参考书的:
它把一个元素从保存的区间拷贝到局部临时对象中。在我们的例子里,这个元素是一个auto_ptr,所以这个拷贝操作默默地把被拷贝的auto_ptr——vector中的那个——设为NULL。另外,当pivotValue出了生存期,它会自动删除指向的Widget。这时sort调用返回了,vector的内容已经改变了,而且至少一个Widget已经被删除了。
其实这个很容易理解,就是因为是auto_ptr容器,如果调用容器的操作涉及到容器元素转移的会造成把容器原数据的置为NULL,并且元素会被删除,删除个数是递归的个数。
条目八《永不建立auto_ptr的容器》的更多相关文章
- 切勿创建包括auto_ptr的容器对象
当你拷贝一个auto_ptr时,它所指向的对象的全部权被移交到拷入的auto_ptr上,而它自身被置为NULL.我的理解是:拷贝一个auto_ptr意味着改变它的值.比如: auto_ptr&l ...
- STL学习系列八:Set和multiset容器
1.set/multiset的简介 set是一个集合容器,其中所包含的元素是唯一的,集合中的元素按一定的顺序排列.元素插入过程是按排序规则插入,所以不能指定插入位置. set采用红黑树变体的数据结构实 ...
- .Net Core微服务入门全纪录(八)——Docker Compose与容器网络
Tips:本篇已加入系列文章阅读目录,可点击查看更多相关文章. 前言 上一篇[.Net Core微服务入门全纪录(七)--IdentityServer4-授权认证]中使用IdentityServer4 ...
- stl学习记录(1)
Effective STL 中文版学习记录 条款4 判断容器是否为空 使用empty而不是size().size()操作在实现上不是一个时间常数操作条款5 尽量使用区间成员函数代替它们的单元素兄弟.S ...
- c++继承构造子类调用父类构造函数的问题及关于容器指针的问题及当容器里储存指针时,记得要手动释放
看下面的一个问题: class Person { private: string name; public: Person(const string& s=""){ nam ...
- docker容器修改时区(java应用log信息与标准容器时间有八个小时时间差)
在docker容器中运行的java应用打出的日志时间和通过date -R方式获取的容器标准时间有八个小时时间差- 因为docker容器的原生时区为0时区,为了和国内时区保持一致,需要把容器时区调为东八 ...
- 在docker for windows建立mssql容器后,ssms连接mssql出现错误号码18456的问题
在docker for windows建立mssql容器后,ssms连接mssql出现错误号码18456的问题 笔者提供一个可能会没考虑到的点. 请检查本机是否安装了mssql!!! 请检查本机的ms ...
- C++ 顺序容器
<C++ Primer 4th>读书笔记 顺序容器内的元素按其位置存储和访问.容器类共享公共的接口,每种容器类型提供一组不同的时间和功能折衷方案.通常不需要修改代码,只需改变类型声明,用一 ...
- C++ Primer 学习笔记_38_STL实践与分析(12)--集成的应用程序容器:文本查询程序
STL实践与分析 --容器的综合应用:文本查询程序 引言: 本章中最重点的实例.由于不须要用到multiset与multimap的内容.于是将这一小节提到了前面.通过这个实例程序,大师分析问题的智慧, ...
随机推荐
- 关于FPGA设计16位乘法器的两…
原文地址:关于FPGA设计16位乘法器的两种算法作者:ChrisChan 部分原代码如下: 用特权的右移算法虽复杂点,但节省不少LEs,如下图: 用左移算法尽管浅显易懂,但因每次都会从最右端移位,会占 ...
- 【原】Coursera—Andrew Ng机器学习—课程笔记 Lecture 6_Logistic Regression 逻辑回归
Lecture6 Logistic Regression 逻辑回归 6.1 分类问题 Classification6.2 假设表示 Hypothesis Representation6.3 决策边界 ...
- Linux 搭建NFS文件服务器实现文件共享
我们接着玩Linux,O(∩_∩)O哈哈~ 1.什么是nfs NFS(Network File System)即网络文件系统,是FreeBSD支持的文件系统中的一种,它允许网络中的计算机之间通过TCP ...
- 268. Missing Number序列中遗失的数字
[抄题]: Given an array containing n distinct numbers taken from 0, 1, 2, ..., n, find the one that is ...
- 一个虚拟机网络的XML描述
<?xml version="1.0" encoding="utf-8"?> <VNET> <ID>1</ID> ...
- 面试题:Java必知必会:异常机制详解 背1
一.Java异常概述 在Java中,所有的事件都能由类描述,Java中的异常就是由java.lang包下的异常类描述的. Trowable是所有异常的超类. 他的常用方法printStackTrec ...
- 面试题:SpringMVC的工作流程
SpringMVC是当今最主流的Web MVC框架,没有之一,要做一名合格的JavaWeb工程师,学好它势在必行! 与Struts2原理不同,SpringMVC是通过最基础最传统的servlet来实现 ...
- WebDriverWait等设置等待时间和超时时间
1.显示等待 等待页面加载完成,找到某个条件发生后再继续执行后续代码,如果超过设置时间检测不到则抛出异常 WebDriverWait(driver, timeout, poll_frequency=0 ...
- SQLite在php中的接口
sqlite是一种比较轻型的嵌入式数据库,它与 SQL 之间的不同,为什么需要它,以及它的应用程序数据库处理方式.SQLite是一个软件库,实现了自给自足的.无服务器的.零配置的.事务性的 SQL 数 ...
- React项目中的registerServiceWorker的作用
在公司的React前端项目中,发现有一个registerServiceWorker.js文件, 很久都没弄明白这个文件是干什么用的,查询了一些资料后,了解了一些 service worker是在后台运 ...