【发布时间】:2010-06-30 16:51:46
【问题描述】:
标题几乎概括了我的问题。为什么不能做以下检查空指针?
auto_ptr<char> p( some_expression );
// ...
if ( !p ) // error
必须改为这样做:
if ( !p.get() ) // OK
为什么auto_ptr<T> 不直接定义operator!()?
【问题讨论】:
标题几乎概括了我的问题。为什么不能做以下检查空指针?
auto_ptr<char> p( some_expression );
// ...
if ( !p ) // error
必须改为这样做:
if ( !p.get() ) // OK
为什么auto_ptr<T> 不直接定义operator!()?
【问题讨论】:
它的设计似乎有错误。这将在 C++0x 中修复。 unique_ptr(替换auto_ptr)包含explicit operator bool() const;
引用新 C++ 标准:
类模板 auto_ptr 已弃用。 [注意:类模板 unique_ptr (20.9.10) 提供了一个 更好的解决方案。 ——尾注]
澄清一下:
问:a.get() == 0 有什么问题?
答:@987654325 没有问题@,但是智能指针可以让你使用它们,因为它们是真正的指针。额外的operator bool() 为您提供了这样的选择。我认为,使auto_ptr 被弃用的真正原因是它没有直观的设计。但是新标准中的operator bool 为unique_ptr 意味着没有理由不拥有它。
【讨论】:
explicit 是什么意思?我只见过构造函数。
auto_ptr 并不是为了更好的指针而设计的,它有一个以可靠的异常安全方式处理所有权转移的接口。
auto_ptr 视为指针;如果您正在编写可与两者一起使用的通用代码,则必须坚持具有共同语义的操作。由于您现在已经排除了复制、赋值和破坏,所以您没有任何事情无法通过仅获取指针值的函数实现,如果您有 auto_ptr,您可以安全地将 get() 传递给原始指针版本。
explicit。拥有explicit 转换运算符是一个新的 C++0x 功能(C++0x 中的另一个微妙变化;直到我看到 @Terry 的评论并想“那是什么疯狂?!”,我才知道它。但是,事实上,他是对的 :-P)。
简单地说,它应该定义了operator !()。 auto_ptr 不是一个设计良好的容器。 boost 中的智能指针定义了operator bool() 转换运算符,可以用operator !() 取反。这将使您的if(!p) 编译并按预期工作。
【讨论】:
auto_ptr 不是一个设计良好的容器" 总结得很好。
auto_ptr 不是容器。还有为什么要定义operator!()?如果您要提出这一主张,那么我认为您需要证明这一主张的合理性。我看不出有任何内在的理由来定义它;并不是说if (a.get() == 0) 不清楚或难以使用。
布尔转换存在问题。它允许几乎总是很痛苦的语法。
幸运的是,有一个解决方案:Safe Bool 成语。
转换为bool 的问题在于隐式转换很危险。
std::auto_ptr<T> p = ..., q = ....;
if (p < q) // uh ?
因此,operator bool() const 是可憎的。要么你提供一个显式的方法......要么你使用安全的布尔成语。
这个习语的想法是给你一个类型的实例,它的操作子集非常少,而且几乎没有隐式转换会给你带来麻烦的情况。这是通过使用指向成员函数的指针来完成的。
if (p) 和 if (!p) 这样的操作是有意义的,但 if (p < q) 将无法编译。
仔细阅读链接以获得完整的解决方案,您就会明白为什么不设置operator bool() const 是个好主意。
【讨论】:
我怀疑是因为预计将auto_ptrs 传递给 null 将是一种罕见的情况,以避免添加额外的接口,并在实际检查 null 时使其明确。
【讨论】: