std::auto_ptr不能用在STL的container,为什么?

sencrus 2009-04-30 11:35:50
如题,请各位帮帮忙!
...全文
598 10 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
10 条回复
切换为时间正序
请发表友善的回复…
发表回复
Jinhao 2009-04-30
  • 打赏
  • 举报
回复
因为std::auto_ptr是转移语义,而STL容器的元素必须是值语义,也就是拷贝语义的。

比如,STL容器都是以副本的形式来保存元素。
std::vector<int> v;
int a = 1;
v.push_back(a);
v[0]也是值为1的int,但不是a..仅仅是一个副本.a的值也并未被改变.

再来看std::auto_ptr
std::auto_ptr<int> p1(new int);
std::auto_ptr<int> p2 = p1;
p2的构造修改了p1的值,使p1交出了对动态分配的int的引用权.此时p1不再引用动态int.这就是转移语义.

从语义上,这两个就不兼容.
另外,std::auto_ptr为了达到转移语义的要求,只提供了这样的一个拷贝构造函数
auto_ptr(auto_ptr&); 而不是通常情况看到的T(const T&); 这就是一个非值语义的表现.

而std::vector因为对元素类型要求是值语义的,所以必须要求元素类型提供T(const T&)的拷贝构造函数.
  • 打赏
  • 举报
回复
http://hi.baidu.com/klcstudy/blog/item/ea194066c2106e27ab184c89.html

这里有替代办法
liliangbao 2009-04-30
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 lingyin55 的回复:]
使用时要注意std::auto_ptr的两个局限性:

它不能作为container 的元素。
它采用了所有权转移的机制,因此不符合STL container 元素的要求。

它不能用于动态创建的数组。
可能是因为大部分时候用std::vector就很合适了,所以没有与auto_ptr相对应的auto_array。不过如果真的有特殊需要的话,也很容易仿照 std::auto_ptr写个auto_array。

http://blog.sina.com.cn/s/blog_46d185020100026b.html
[/Quote]
Up
liao05050075 2009-04-30
  • 打赏
  • 举报
回复
可见智能指针并非对任何情况都智能。使用auto_ptr要知道:
1. 智能指针不能共享指向对象的所有权
2. 智能指针不能指向数组。因为其实现中调用的是delete而非delete[]
3. 智能指针不是万能的
4. 智能指针不能作为容器类的元素。例如:
template<class T>
void container::insert(const T &value)
{
..........
X = value;
..........
}
事实上在stl中,所有的container要内部拷贝所传参数的值时都是传的const类型的值。因此无法用auto_ptr传进去。
、、、、、、、、、、、、、、、、、、、、、
一句话: //一句话,假定有一个动态分配的int空间,则在一个时刻只能有一个auto_ptr指针指向他!
这就是所有权的独占性
yshuise 2009-04-30
  • 打赏
  • 举报
回复
比如:
vector<std::auto<ptr> > vec;
std::auto<ptr> r = vec[0] //因为使用权转移,r 有值,vec[0]为空。容器的值就没有了,我们不不想这样。
pengzhixi 2009-04-30
  • 打赏
  • 举报
回复
因为容器的实现很多都是存放副本的,所以如果你用auto_ptr时,一旦发生拷贝,赋值这些操作那么你就会发生控制权的转移.比如赋值就会导致赋值符号右边的控制权转移到赋值符号左边,也就以为着改边了赋值符号右边的变量
lingyin55 2009-04-30
  • 打赏
  • 举报
回复
使用时要注意std::auto_ptr的两个局限性:

它不能作为container 的元素。
它采用了所有权转移的机制,因此不符合STL container 元素的要求。

它不能用于动态创建的数组。
可能是因为大部分时候用std::vector就很合适了,所以没有与auto_ptr相对应的auto_array。不过如果真的有特殊需要的话,也很容易仿照 std::auto_ptr写个auto_array。

http://blog.sina.com.cn/s/blog_46d185020100026b.html
jame2001 2009-04-30
  • 打赏
  • 举报
回复
用 boost::shared_ptr 或 boost::weak_ptr取代


std::auto_ptr很多的时候并不能满足我们的要求,比如她不能用在STL的container中。boost的smart_ptr中提供了4种智能指针和2种智能指针数组来作为std::auto_ptr的补充。


shared_ptr<boost/shared_ptr.hpp>:使用shared_ptr进行对象的生存期自动管理,使得分享资源所有权变得有效且安全.

scoped_ptr<boost/scoped_ptr.hpp>:用于确保能够正确地删除动态分配的对象。scoped_ptr 有着与std::auto_ptr类似的特性,而最大的区别在于它不能转让所有权而auto_ptr可以。事实上,scoped_ptr永远不能被复制或被赋值!scoped_ptr 拥有它所指向的资源的所有权,并永远不会放弃这个所有权。

weak_ptr<boost/weak_ptr.hpp>:weak_ptr 是 shared_ptr 的观察员。它不会干扰shared_ptr所共享的所有权。当一个被weak_ptr所观察的 shared_ptr 要释放它的资源时,它会把相关的 weak_ptr的指针设为空。使用此辅助指针一般是防止悬空指针。
yshuise 2009-04-30
  • 打赏
  • 举报
回复
stl 的容器是值语义。是以拷贝的方式进行。
std::auto_ptr他会转移使用权限。用boost::shared_ptr
majun01 2009-04-30
  • 打赏
  • 举报
回复

65,186

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧