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的元素,返回指 ...
随机推荐
- LeetCode 409——最长回文串
1. 题目 2. 解答 我们先来看一看回文子串的规律,如果回文子串的长度为偶数,那么其中所有的每个元素都出现了偶数次:如果回文子串的长度为奇数,那么有一个元素出现了奇数次而其余每个元素都出现了偶数次. ...
- Linux-Ubuntu目录
ubuntu没有盘符这个概念,只有一个根目录/,所有文件都在它下面 /:根目录,一般根目录下只存放目录,在Linux下有且只有一个根目录.所有的东西都是从这里开始.当你在终端里输入“/home”,你其 ...
- python + 爬虫 + fiddler + 夜神模拟器 爬取app(1)
抓包 抓包是爬虫里面经常用到的一个词,完整的应该叫做抓取数据请求响应包 ,而Fiddler这款工具就是干这个的 普通https抓包设置 打开Fiddler ------> Options .然后 ...
- linux 代码更新-打包-重启脚本
#! /bin/sh base=/home/project/myblog cd $base git pull ] then echo "Error in git pull!!! Stop d ...
- Python学习-------变量和简单的数据类型(String)
1.变量命名和使用 变量命名规则:a.变量名只能包含(字母 数字 下划线),且变量不能以数字开头,例如:变量 s_1(正确),变量1_s(错误) b.变量名不能包含空格,可以使用下划线来间隔 ...
- 想使用 MongoDB ,你应该了解这8个方面!
想使用 MongoDB ,你应该了解这8个方面! 应用性能高低依赖于数据库性能,MongoDB 是一个基于分布式文件存储的数据库.由 C++ 语言编写,旨在为 WEB 应用提供可扩展的高性能数据存储解 ...
- 10 mysql选错索引
10 mysql选错索引 在mysql表中可以支持多个索引,有的sql不指定使用哪个索引,由mysql自己来决定,但是有时候mysql选错了索引,导致执行很慢. 例子 CREATE TABLE `t1 ...
- java:JavaScript2:(setTimeout定时器,history.go()前进/后退,navigator.userAgent判断浏览器,location.href,五种方法获取标签属性,setAttribute,innerHTML,三种方法获取form表单信息,JS表单验证,DOM对象,form表单操作)
1.open,setTimeout,setInterval,clearInterval,clearTimeout <!DOCTYPE> <html> <head> ...
- 双系统正确卸载Ubuntu系统
双系统正确卸载Ubuntu系统 安装系统后由于显卡驱动问题,无法开机,从而只能卸载重装,重装过程如下. 第一步:下载需要的工具包,这里我用的是MBRfix, 可以直接从我分享的网盘链接下载,密码gw ...
- session 的理解