将 auto_ptr 传递给需要常量引用 auto_ptr 的函数有什么危险?
Nicolai Josuttis 在他的书“The C++ Standard Library - A Tutorial and Reference”中,第 44 页写道:
根据auto_ptrs的概念,可以通过使用常量引用将所有权转移到函数中。这是非常危险的,因为人们通常期望当您将对象作为常量引用传递时不会被修改。幸运的是,后来的设计决定使得 auto_ptr 的危险性降低了。通过一些棘手的实现技术,通过不断的引用来转移所有权是不可能的。事实上,您无法更改任何常量 auto_ptr 的所有权:...
如果不可能使用常量引用更改所有权,为什么上面的表达式“这非常危险”和“不太危险”?
Nicolai Josuttis, in his book "The C++ Standard Library - A Tutorial and Reference", writes, at page 44, the following paragraph :
According to the concept of auto_ptrs, it is possible to transfer ownership into a function by using a constant reference. This is very dangerous because people usually expect that an object won't get modified when you pass it as a constant reference. Fortunately, there was a late design decision that made auto_ptrs less dangerous. By some tricky implementation techniques, transfer of ownership is not possible with constant references. In fact, you can't change the ownership of any constant auto_ptr: …
If is not possible to change ownership with a constant reference, why the expressions "This is very dangerous" and "less dangerous" above ?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
总结评论:
“这非常危险”指的是
std::auto_ptr
的复制构造函数(转移所有权)采用 const 引用参数 – this完全违反了const- Correctness。“危险性较小”是指复制构造函数(现在采用非常量引用)可以完全转移所有权;这仍然很危险,只是不像复制构造函数采用 const 引用那样危险。
std::auto_ptr<>
的这一方面普遍被认为是该类中的一个缺陷,以至于它通常被认为是无法使用的损坏。因此,boost::scoped_ptr
和boost::shared_ptr<>
在很大程度上被认为是 C++03 的“真正”智能指针,而在 C++11 中std: :auto_ptr<>
已完全弃用,取而代之的是std::unique_ptr
(在 C++17 中完全删除)。更新:从 Boost 1.57 开始,现在使用 Boost.Move 库提供了
std::unique_ptr<>
的 C++03 模拟,应该使用它而不是boost::scoped_ptr<>
:boost::movelib ::unique_ptr<>
。Summing up comments:
"This is very dangerous" refers to when
std::auto_ptr<>
's copy constructor (which transfers ownership) took a const reference argument – this is a complete violation of const-correctness."Less dangerous" refers to the fact that the copy constructor (which now takes a non-const reference) can transfer ownership at all; this is still dangerous, just not as dangerous as when the copy constructor took a const reference.
This aspect of
std::auto_ptr<>
is universally considered a flaw in the class, to the extent that it's generally considered unusably broken. Consequently,boost::scoped_ptr<>
andboost::shared_ptr<>
are largely considered the "real" smart pointers of C++03, and in C++11std::auto_ptr<>
is deprecated altogether in favor ofstd::unique_ptr<>
(and removed entirely in C++17).Update: As of Boost 1.57, the Boost.Move library now supplies a C++03 emulation of
std::unique_ptr<>
which should be used rather thanboost::scoped_ptr<>
:boost::movelib::unique_ptr<>
.