昨天看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的元素的更多相关文章

  1. 3205: 数组做函数参数--数组元素求和1--C语言

    3205: 数组做函数参数--数组元素求和1--C语言 时间限制: 1 Sec  内存限制: 128 MB提交: 178  解决: 139[提交][状态][讨论版][命题人:smallgyy] 题目描 ...

  2. 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 W​i​​ assigne ...

  3. 【C++】Vector判断元素是否存在,去重,求交集,求并集

    1 #include <iostream> 2 #include <vector> 3 #include <algorithm> //sort函数.交并补函数 4 ...

  4. vector查找元素

    转自:http://hi.baidu.com/chain2008/blog/item/821744585e12c5c89c8204e8.html 今天又忘了怎么在vector中查找某一个值..唉..每 ...

  5. vector删除元素与清除内存空洞

    问题:stl中的vector容器经常造成删除假象,这对于c++程序猿来说是极其讨厌的,<effective stl>大师已经将之列为第17条,使用交换技巧来修整过剩容量. 内存空洞这个名词 ...

  6. C++ vector清空元素的三种方法

    #include <iostream> #include <vector> using namespace std; //STL vector的几种清空容器(删除)办法 voi ...

  7. vector删除元素浅析

    <<effectSTL>>书中提到erase-remove方法  即c.rease(remove(c.begin(),c.end(),1963),c.end()) 关于remo ...

  8. C++之vector中元素删除

    今天在删除vector中的元素中遇到一个问题,这里记录下来以便以后查阅. 预备知识:用到了erase()函数,对于一个容器c来说,假设迭代器为p,那么执行: c.erase(p)之后就删除了容器c中p ...

  9. C++中标准容器Vector,元素操作.insert()小结

    insert() 函数有以下三种用法: iterator insert( iterator loc, const TYPE &val );  //在指定位置loc前插入值为val的元素,返回指 ...

随机推荐

  1. php array function

    说明:不特殊说明都支持php4,5,7 参考:https://www.php.net/manual/zh/ref.array.php   is_array ( mixed $var ) : bool ...

  2. Android共享元素场景切换动画的实现

    安卓5.0系统引入了共享元素,能做出非常炫酷的场景切换效果,这让人非常兴奋同时非常蛋疼,因为低版本没法使用啊,所以今天就跟大家分享一下自己写的一个库,其实只有2个文件而已就可以兼容安卓5.0以下的版本 ...

  3. ControlTemplate in WPF ——ScrollBar

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" x ...

  4. OpenFlow/SDN 的缘起与发展

    目录 文章目录 目录 从虚拟机动态迁移对大二层网络的需求说起 OpenFlow 起源 从 OpenFlow 扩展为 SDN OpenFlow 的应用场景 网络虚拟化 – FlowVisor 负载均衡 ...

  5. LeetCode.1030-曼哈顿距离排序矩阵单元格(Matrix Cells in Distance Order)

    这是小川的第384次更新,第412篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第246题(顺位题号是1030).我们给出一个矩阵,其中R行和C列具有整数坐标(r,c)的 ...

  6. javase程序设计上机作业2

    package javaxgp.teacher.test; import java.util.Scanner; public class Demo3 { public static void main ...

  7. python_面试题_DB相关问题

    1.mysql部分 问题 问题1:mysql的存储引擎 问题2:mysql的索引机制 问题3:mysql的事务以及事务隔离级别 问题4:mvcc/GAP lock是做什么的 问题5:mysql的悲观锁 ...

  8. TCP中三次挥手四次握手

    1.TCP连接 手机能够使用联网功能是因为手机底层实现了TCP/IP协议,可以使手机终端通过无线网络建立TCP连接.TCP协议可以对上层网络提供接口,使上层网络数据的传输建立在“无差别”的网络之上. ...

  9. 【Qt开发】QTableWidget设置根据内容调整列宽和行高

    QTableWidget要调整表格行宽主要涉及以下一个函数 1.resizeColumnsToContents();                      根据内容调整列宽            ...

  10. mybati代码生成器 mybatis-generator

    Mybatis代码生成器,用于快速生成代码 代码 https://github.com/wangxinforme/mybatis-generator