【问题标题】:Why doesn't auto_ptr<T> have operator!() defined?为什么 auto_ptr<T> 没有定义 operator!() ?
【发布时间】:2010-06-30 16:51:46
【问题描述】:

标题几乎概括了我的问题。为什么不能做以下检查空指针?

auto_ptr<char> p( some_expression );
// ...
if ( !p )  // error

必须改为这样做:

if ( !p.get() ) // OK

为什么auto_ptr&lt;T&gt; 不直接定义operator!()

【问题讨论】:

标签: c++ auto-ptr


【解决方案1】:

它的设计似乎有错误。这将在 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 boolunique_ptr 意味着没有理由不拥有它。

【讨论】:

  • “愚蠢”问题:这里的explicit 是什么意思?我只见过构造函数。
  • 这意味着它对构造函数的意义相同 - 构造函数或转换运算符不参与当您尝试将对象传递给期望参数为 a 的函数时发生的隐式转换舞蹈不同类型
  • @stinky472:从根本上说,智能指针不能具有与指针完全相同的公共接口,否则(根据定义)它们不会是智能的。特别是 auto_ptr 并不是为了更好的指针而设计的,它有一个以可靠的异常安全方式处理所有权转移的接口。
  • @stinky472:我认为通用代码参数是假的。您不能将auto_ptr 视为指针;如果您正在编写可与两者一起使用的通用代码,则必须坚持具有共同语义的操作。由于您现在已经排除了复制、赋值和破坏,所以您没有任何事情无法通过仅获取指针值的函数实现,如果您有 auto_ptr,您可以安全地将 get() 传递给原始指针版本。
  • @Matthieu:在 C++03 中,只有构造函数可以是 explicit。拥有explicit 转换运算符是一个新的 C++0x 功能(C++0x 中的另一个微妙变化;直到我看到 @Terry 的评论并想“那是什么疯狂?!”,我才知道它。但是,事实上,他是对的 :-P)。
【解决方案2】:

简单地说,它应该定义了operator !()auto_ptr 不是一个设计良好的容器。 boost 中的智能指针定义了operator bool() 转换运算符,可以用operator !() 取反。这将使您的if(!p) 编译并按预期工作。

【讨论】:

  • "auto_ptr 不是一个设计良好的容器" 总结得很好。
  • auto_ptr 不是容器。还有为什么要定义operator!()?如果您要提出这一主张,那么我认为您需要证明这一主张的合理性。我看不出有任何内在的理由来定义它;并不是说if (a.get() == 0) 不清楚或难以使用。
  • 如果某个东西被设计成像一个更智能的指针,那么它的接口应该像一个指针。
  • @Charles 我想容器不是最准确的词。我应该怎么称呼它?
  • @Charles,我喜欢你为它辩护的方式,但你不同意这很糟糕吗?如果它的用法与指针的用法不同,那么它的名称选择得非常糟糕。
【解决方案3】:

布尔转换存在问题。它允许几乎总是很痛苦的语法。

幸运的是,有一个解决方案:Safe Bool 成语。

转换为bool 的问题在于隐式转换很危险。

std::auto_ptr<T> p = ..., q = ....;

if (p < q) // uh ?

因此,operator bool() const 是可憎的。要么你提供一个显式的方法......要么你使用安全的布尔成语。

这个习语的想法是给你一个类型的实例,它的操作子集非常少,而且几乎没有隐式转换会给你带来麻烦的情况。这是通过使用指向成员函数的指针来完成的。

if (p)if (!p) 这样的操作是有意义的,但 if (p &lt; q) 将无法编译。

仔细阅读链接以获得完整的解决方案,您就会明白为什么不设置operator bool() const 是个好主意。

【讨论】:

    【解决方案4】:

    我怀疑是因为预计将auto_ptrs 传递给 null 将是一种罕见的情况,以避免添加额外的接口,并在实际检查 null 时使其明确。

    【讨论】:

    • 鉴于 auto_ptr::operator= 转移所有权并将源 auto_ptr 设置为 null,因此 auto_ptr 为 null 可能相当普遍。
    猜你喜欢
    • 1970-01-01
    • 2021-04-16
    • 1970-01-01
    • 2014-04-20
    • 1970-01-01
    • 2010-11-09
    • 2015-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多