auto_ptr为什么不能做为vector的元素
昨天看effectve c++的时候,发现了auto_ptr这个东西。由于我待过的公司都是用的老版c++,代码里智能指针什么的完全没有出现过,都是直接操作的原始指针。虽说我很少出错,但是总归还是不太安全。言归正传,说回auto_ptr,这个东西一开始我也见过,但是当时在赶项目也就没有怎么上心,这回正好看到了,就详细了解下。
在effiectev c++中我了解到,这是老版c++里的智能指针(之前我只知道c++11里的share_ptr和unique_ptr),同一个对象从始至终只会有一个auto_ptr指向它,也就是说当指向某个对象的auto_ptr被拷贝时(拷贝构造或者是赋值),原auto_ptr会被置为NULL。当指向对象的auto_ptr离开作用域后,会自动调用析构函数,从而达到防止资源泄露的目的。
很自然的,我想将我最近的新项目由操作裸指针改为智能指针,因为在项目中用到了STL标准容器,所以打算先用vector测试下auto_ptr。测试代码如下:
#include<iostream>
#include<vector>
#include<memory> class Test{
public:
Test() {
std::cout << "init" << std::endl;
} ~Test() {
std::cout << "del" << std::endl;
}
}; int main()
{
std::auto_ptr<Test> ap(new Test()); std::vector<std::auto_ptr<Test> > vec;
vec.push_back(ap); std::cout << ap.get() << std::endl;
return ;
}
编译时,提示auto_ptr过时的警告就不提了,报错如下:
/usr/include/c++//ext/new_allocator.h::: error: no matching function for call to ‘std::auto_ptr<Test>::auto_ptr(const std::auto_ptr<Test>&)’
{ ::new((void *)__p) _Up(std::forward<_Args>(__args)...); }
当时可能警告加报错信息太长,我没有看到这个const。。。然后想了很久想不通为什么不行,我当时的理解是vector将auto_ptr拷贝进去,原auto_ptr将变为0。然后怀疑自己将vector的push_back操作记错了,打开stl源码解析,找到vector加入元素时构造的函数:
template <class T1, class T2>
inline void construct(T1* p, const T2& value)
{
new (p) T1(value);
}
嗯?我没记错啊,为什么不能呢?然后我去网上搜了下,知道真相的我眼泪掉了下来。很简单:
因为将auto_ptr拷贝时需要对原auto_ptr进行修改,也就是将原auto_ptr置为NULL,所以不能支持以const的方式进行拷贝构造!
也就是说,auto_ptr是不能做为STL标准容器的元素的。
对于这个疑问的出现,我想一方面是自己不够细心,没有仔细看报错的含义;另一方面是自己的思维还有点欠缺,明明知识点都知道,但是没联想到。
auto_ptr为什么不能做为vector的元素的更多相关文章
- 3205: 数组做函数参数--数组元素求和1--C语言
3205: 数组做函数参数--数组元素求和1--C语言 时间限制: 1 Sec 内存限制: 128 MB提交: 178 解决: 139[提交][状态][讨论版][命题人:smallgyy] 题目描 ...
- PAT 甲级 1053 Path of Equal Weight (30 分)(dfs,vector内元素排序,有一小坑点)
1053 Path of Equal Weight (30 分) Given a non-empty tree with root R, and with weight Wi assigne ...
- 【C++】Vector判断元素是否存在,去重,求交集,求并集
1 #include <iostream> 2 #include <vector> 3 #include <algorithm> //sort函数.交并补函数 4 ...
- vector查找元素
转自:http://hi.baidu.com/chain2008/blog/item/821744585e12c5c89c8204e8.html 今天又忘了怎么在vector中查找某一个值..唉..每 ...
- vector删除元素与清除内存空洞
问题:stl中的vector容器经常造成删除假象,这对于c++程序猿来说是极其讨厌的,<effective stl>大师已经将之列为第17条,使用交换技巧来修整过剩容量. 内存空洞这个名词 ...
- C++ vector清空元素的三种方法
#include <iostream> #include <vector> using namespace std; //STL vector的几种清空容器(删除)办法 voi ...
- vector删除元素浅析
<<effectSTL>>书中提到erase-remove方法 即c.rease(remove(c.begin(),c.end(),1963),c.end()) 关于remo ...
- C++之vector中元素删除
今天在删除vector中的元素中遇到一个问题,这里记录下来以便以后查阅. 预备知识:用到了erase()函数,对于一个容器c来说,假设迭代器为p,那么执行: c.erase(p)之后就删除了容器c中p ...
- C++中标准容器Vector,元素操作.insert()小结
insert() 函数有以下三种用法: iterator insert( iterator loc, const TYPE &val ); //在指定位置loc前插入值为val的元素,返回指 ...
随机推荐
- 让socket端口不被子进程继承
有两个程序A,B A绑定端口8000,然后用system函数启动程序B,然后再把A杀掉,这个时候再重启A的时候会发现绑定端口失败, 原因是端口被B绑定了,实际上是被继承了,为了避免这种情况,需要对主s ...
- 1.7 本机单步调试(Intellij IDEA)
先编译好要调试的程序. 1.设置断点 选定要设置断点的代码行,在行号的区域后面单击鼠标左键即可. 2.开启调试会话 点击红色箭头指向的小虫子,开始进入调试. IDE下方出现Debug视图,红色的箭头指 ...
- 深度学习基础——Epoch、Iteration、Batchsize
原文地址:https://www.cnblogs.com/Johnny-z6951/p/11201081.html 梯度下降是一个在机器学习中用于寻找较佳结果(曲线的最小值)的迭代优化算法.梯度的含义 ...
- 如何手写实现简易的Dubbo[z]
[z]https://juejin.im/post/5ccf8dec6fb9a0321c45ebb5 前言 结束了集群容错和服务发布原理这两个小专题之后,有朋友问我服务引用什么时候开始,本篇为服务引用 ...
- 前端必须掌握的 nginx 技能(2)
概述 作为一个前端,我觉得必须要学会使用 nginx 干下面几件事: 代理静态资源 设置反向代理(添加https) 设置缓存 设置 log 部署 smtp 服务 设置 redis 缓存(选) 下面我按 ...
- Cinder LVM backend cinder-volume service down
目录 文章目录 目录 问题 调查 解决 问题 [stack@manager ~]$ cinder service-list +------------------+------------------ ...
- Linux环境Nginx安装
开始前,请确认gcc g++开发类库是否装好,默认已经安装. ububtu平台编译环境可以使用以下指令 apt-get install build-essential apt-get install ...
- Windos下navcat连接虚拟机中的mysql
进入mysql命令行, 使用root用户,密码:youpassword(你的root密码)连接到mysql服务器: # mysql -u root -proot mysql>GRANT ALL ...
- CDH日常运维
1/ 作业有问题: 查log,没log再跑一次查log. 如果没有log的情况,比如hiveserver2挂了,查strr. 2/ 查集群名字 #看hdfs集群的名字,在cdh的hdfs配置中查:na ...
- Elasticsearch-索引新数据(创建索引、添加数据)
ES-索引新数据 0.通过mapping映射新建索引 CURL -XPOST 'localhost:9200/test/index?pretty' -d '{ "mappings" ...