您的位置:首页 > 其它

为什么auto_ptr智能指针不能作为STL标准容器的元素

2015-03-14 17:00 295 查看
为什么auto_ptr不可以作为STL标准容器的元素

假如有这样的一段代码,是否能够运行?

?
答案是否定的,甚至这段代码是无法编译通过的。

错误出在这一行:

?
auto_ptr的拷贝构造函数是这样写的:

?
可以看出来, 在拷贝构造一个auto_tr的时候, 必需要把参数的那个auto_ptr给release掉,然后在把参数的_M_ptr指针赋值给自己的_M_ptr指针。补充说明一下, _M_ptr是auto_ptr的一个成员,指向auto_ptr管理的那块内存,也就是在auto_ptr生命周期之外被释放掉的那块内存。

当看到这里的时候,整个问题已经能解释通了。STL容器在分配内存的时候,必须要能够拷贝构造容器的元素。而且拷贝构造的时候,不能修改原来元素的值。而auto_ptr在拷贝构造的时候,一定会修改元素的值。所以STL元素不能使用auto_ptr。

不过,还有一个很重要的问题没有解释。那就是为什么在设计auto_ptr的时候,拷贝构造要修改参数的值呢?

其实这问题很简单,不看代码也可以解释清楚。auto_ptr内部有一个指针成员_M_ptr,指向它所管理的那块内存。而拷贝构造的时候,首先把参数的_M_ptr的值赋值给自己的_M_ptr,然后把参数的_M_ptr指针设成NULL,。如果不这样设计,而是直接把参数的_M_ptr指针赋值给自己的, 那么两个auto_ptr的_M_ptr指向同一块内存,在析构auto_ptr的时候就会出问题: 假如两个auto_ptr的_M_ptr指针指向了同一块内存,那么第一个析构的那个auto_ptr指针就把_M_ptr指向的内存释放掉了,造成后一个auto_ptr在析构时释要放一块已经被释放掉的内存,这明显不科学,会产生程序的段错误而crash掉。

而shared_ptr则不存在这个问题, 在拷贝构造和赋值操作的时候,只会引起公用的引用计数的+1,不存在拷贝构造和赋值操作的参数不能是const的问题。

总结:

1 auto_ptr不能作为STL标准容器的元素。

2 auto_ptr在拷贝复制和赋值操作时,都会改变参数。这是因为两个auto_ptr不能管理同一块内存。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: