auto_ptr在stl使用中的问题

auto_ptr说明:
C++的auto_ptr所做的事情,就是动态分配对象以及当对象不再需要时自动执行清理。
使用std::auto_ptr,要#include <memory>。
auto_ptr作用:

c++中可以通过auto_ptr实现对内存的管理,当auto_ptr绑定指针后,在auto_ptr结束的时候释放地址所指向的内存

关于STL中使用auto_ptr的问题:

我们通过一段代码来观察:

#include <memory>
#include <iostream>
#include <vector>
using namespace std;


int main()
{
    vector<auto_ptr<int>> v(10);
    for(int i=0;i<10;i++)
    {
         v[i] = auto_ptr<int>(new int(1));
    }
    for(int i=0;i<10;i++)
    {
         cout<<*v[i]<<endl;
    }
    return 0;
}

查看网上说auto_ptr不能再stl中使用,但是在vs2017编写代码并编译运行是没有问题的,所以又在网上查找发现不能运行的挺多的,后来在linux下编译运行:

g++ auto_ptr.cpp

发现编译不能通过

auto_ptr.cpp: In function ‘int main()’:
auto_ptr.cpp:9:24: error: ‘>>’ should be ‘> >’ within a nested template argument list
     vector<auto_ptr<int>> v(10);
                        ^
In file included from /usr/include/c++/5/memory:64:0,
                 from auto_ptr.cpp:1:
/usr/include/c++/5/bits/stl_construct.h: In instantiation of ‘void std::_Construct(_T1*, const _T2&) [with _T1 = std::auto_ptr<int>; _T2 = std::auto_ptr<int>]’:
/usr/include/c++/5/bits/stl_uninitialized.h:202:18:   required from ‘static _ForwardIterator std::__uninitialized_fill_n<_TrivialValueType>::__uninit_fill_n(_ForwardIterator, _Size, const _Tp&) [with _ForwardIterator = std::auto_ptr<int>*; _Size = long unsigned int; _Tp = std::auto_ptr<int>; bool _TrivialValueType = false]’
/usr/include/c++/5/bits/stl_uninitialized.h:247:17:   required from ‘_ForwardIterator std::uninitialized_fill_n(_ForwardIterator, _Size, const _Tp&) [with _ForwardIterator = std::auto_ptr<int>*; _Size = long unsigned int; _Tp = std::auto_ptr<int>]’
/usr/include/c++/5/bits/stl_uninitialized.h:358:39:   required from ‘_ForwardIterator std::__uninitialized_fill_n_a(_ForwardIterator, _Size, const _Tp&, std::allocator<_Tp2>&) [with _ForwardIterator = std::auto_ptr<int>*; _Size = long unsigned int; _Tp = std::auto_ptr<int>; _Tp2 = std::auto_ptr<int>]’
/usr/include/c++/5/bits/stl_vector.h:1301:33:   required from ‘void std::vector<_Tp, _Alloc>::_M_fill_initialize(std::vector<_Tp, _Alloc>::size_type, const value_type&) [with _Tp = std::auto_ptr<int>; _Alloc = std::allocator<std::auto_ptr<int> >; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::value_type = std::auto_ptr<int>]’
/usr/include/c++/5/bits/stl_vector.h:306:27:   required from ‘std::vector<_Tp, _Alloc>::vector(std::vector<_Tp, _Alloc>::size_type, const value_type&, const allocator_type&) [with _Tp = std::auto_ptr<int>; _Alloc = std::allocator<std::auto_ptr<int> >; std::vector<_Tp, _Alloc>::size_type = long unsigned int; std::vector<_Tp, _Alloc>::value_type = std::auto_ptr<int>; std::vector<_Tp, _Alloc>::allocator_type = std::allocator<std::auto_ptr<int> >]’
auto_ptr.cpp:9:31:   required from here
/usr/include/c++/5/bits/stl_construct.h:83:7: error: no matching function for call to ‘std::auto_ptr<int>::auto_ptr(const std::auto_ptr<int>&)’
       ::new(static_cast<void*>(__p)) _T1(__value);
       ^
In file included from /usr/include/c++/5/memory:88:0,
                 from auto_ptr.cpp:1:
/usr/include/c++/5/backward/auto_ptr.h:260:7: note: candidate: std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr_ref<_Tp>) [with _Tp = int]
       auto_ptr(auto_ptr_ref<element_type> __ref) throw()
       ^
/usr/include/c++/5/backward/auto_ptr.h:260:7: note:   no known conversion for argument 1 from ‘const std::auto_ptr<int>’ to ‘std::auto_ptr_ref<int>’
/usr/include/c++/5/backward/auto_ptr.h:125:9: note: candidate: template<class _Tp1> std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr<_Tp1>&)
         auto_ptr(auto_ptr<_Tp1>& __a) throw() : _M_ptr(__a.release()) { }
         ^
/usr/include/c++/5/backward/auto_ptr.h:125:9: note:   template argument deduction/substitution failed:
In file included from /usr/include/c++/5/memory:64:0,
                 from auto_ptr.cpp:1:
/usr/include/c++/5/bits/stl_construct.h:83:7: note:   types ‘std::auto_ptr<_Tp1>’ and ‘const std::auto_ptr<int>’ have incompatible cv-qualifiers
       ::new(static_cast<void*>(__p)) _T1(__value);
       ^
In file included from /usr/include/c++/5/memory:88:0,
                 from auto_ptr.cpp:1:
/usr/include/c++/5/backward/auto_ptr.h:112:7: note: candidate: std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr<_Tp>&) [with _Tp = int] <near match>
       auto_ptr(auto_ptr& __a) throw() : _M_ptr(__a.release()) { }
       ^
/usr/include/c++/5/backward/auto_ptr.h:112:7: note:   conversion of argument 1 would be ill-formed:
In file included from /usr/include/c++/5/memory:64:0,
                 from auto_ptr.cpp:1:
/usr/include/c++/5/bits/stl_construct.h:83:7: error: binding ‘const std::auto_ptr<int>’ to reference of type ‘std::auto_ptr<int>&’ discards qualifiers
       ::new(static_cast<void*>(__p)) _T1(__value);
       ^
In file included from /usr/include/c++/5/memory:88:0,
                 from auto_ptr.cpp:1:
/usr/include/c++/5/backward/auto_ptr.h:103:7: note: candidate: std::auto_ptr<_Tp>::auto_ptr(std::auto_ptr<_Tp>::element_type*) [with _Tp = int; std::auto_ptr<_Tp>::element_type = int]
       auto_ptr(element_type* __p = 0) throw() : _M_ptr(__p) { }
       ^
/usr/include/c++/5/backward/auto_ptr.h:103:7: note:   no known conversion for argument 1 from ‘const std::auto_ptr<int>’ to ‘std::auto_ptr<int>::element_type* {aka int*}’

后来想了一下是不是和编译条件有关系,添加 -std=c++11编译通过:

g++ auto_ptr.cpp -std=c++11

执行:

./a.out

结果:

1
1
1
1
1
1
1
1
1
1

通过测试我们可以发现其实只要指定编译是用c++11标准编译就可以通过,说明auto_ptr在c++11和之前的实现是不一样的。
c++标准规定STL元素必须是“可复制构造的”和“可分配的”。换句话说,必须能够分配或复制一个元素,并且这两个元素在逻辑上是独立的。C++11之前的std: auto_ptr 得实现是不满足此要求。但是auto_ptr是不支持多个auto_ptr指向同一块内存的,所以在执行=和copy操作时会把原先的auto_ptr指向空。
然而STL容器在分配内存的时候,必须要能够拷贝构造容器的元素。而且拷贝构造的时候,不能修改原来元素的值。而auto_ptr在拷贝构造的时候,一定会修改元素的值。所以STL元素不能使用auto_ptr。
所以我们可以大胆的猜测c++11中对auto_ptr的拷贝和=重载做了不同的实现,目前博主还不是太清楚。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值