提问人:anurag86 提问时间:11/9/2019 最后编辑:curiousguyanurag86 更新时间:11/10/2019 访问量:252
为什么unique_ptr有效,但auto_ptr不适用于 STL
Why unique_ptr works but auto_ptr doesn’t with STL
问:
我已经参考了很多关于这些问题的 StackOverflow 链接,其中不能很好地使用 STL 的原因是不符合可复制构造和可分配的要求(因为有一个假的复制构造函数,它基本上转移了所有权)。auto_ptr
std::auto_ptr<>
auto_ptr
但是即使没有复制 ctor 和赋值运算符(它被禁用),那么如何满足可复制构造和可赋值的要求呢?unique_ptr
答:
我假设您指的是将智能指针与 STL 容器一起使用。
auto_ptr
可以,但不应使用,因为它的复制构造函数可能会意外移动数据(它是在 C++11 中添加带有右值引用的移动语义之前设计的)。
unique_ptr
没有复制构造函数,因此它不能在 STL 容器中简单使用。复制指针的操作将不起作用,但这就是它的安全之处。您仍然可以显式使用移动迭代器或 emplace 将不可复制的元素放入容器中。
在容器中使用的示例如下: 那么unique_ptr可以在 stl 集合中安全地使用吗?unique_ptr
评论
vector<int>
unique_ptr
push_back
unique_ptr
emplace_back
你把整个事情倒过来看。
在 C++98/03 中,我们得到了 .这种类型通过假装它支持复制语义来欺骗所有人,而实际上复制它所做的与复制操作非常不同。因此,任何依赖于提供复制语义的类型(如某些容器)都不能很好地获得 .当然,只有当你的代码变得功能失调时,你才会发现,而不是在编译时。auto_ptr
auto_ptr
在 C++11 中,我们得到了 ,这是一个显式不提供复制语义的类型。相反,它提供移动语义,并正确地提供它们。因此,任何依赖于提供复制语义的类型的类型在给定 .unique_ptr
unique_ptr
然而,之所以出现这个原因,是因为在 C++11 中添加了移动对象的概念。当新概念被添加到语言中时,现有工具(如标准库要求)通常会相对于该语言功能进行重新评估。unique_ptr
例如,以前需要复制语义的类型不一定必须保留该要求。需要复制语义的 C++98/03 容器在 C++11 中更新为仅要求(除了)从类型中移动语义。
因此,它并不能满足某些未满足的要求。而是语言更改为不再需要该要求,但仍然在撒谎,因此出于向后兼容性的考虑,我们创建了一种尊重新语言功能并且不对人们撒谎的新类型。unique_ptr
auto_ptr
auto_ptr
评论
auto_ptr看起来像复制可构造/可赋值,因为它具有复制构造函数和赋值运算符。
问题在于它的复制构造函数和赋值没有实现复制语义,而是移动语义。这使得auto_ptr的接口令人惊讶,并使其在内部分配元素的容器(例如向量)中无法使用。
更糟糕的是,在向量中使用auto_ptr格式正确(没有编译错误),但没有有用的行为,这很容易导致未定义的行为(即严重的错误)。
但即使是unique_ptr也没有复制 ctor 和赋值运算符(已禁用)
unique_ptr不需要是可复制的、可构造的或可分配的。对于大多数用例来说,移动、可构造和可分配就足够了。
unique_ptr可以取代auto_ptr的所有用途,并且没有auto_ptr的问题。自 C++11 引入了对移动的unique_ptr和语言支持以来,auto_ptr已被弃用,自 C++17 起,auto_ptr已从标准库中删除。
评论
unique_ptr