【问题标题】:Is a reference of a shared_ptr still a pointer?shared_ptr 的引用仍然是指针吗?
【发布时间】:2017-03-22 16:20:13
【问题描述】:

最近我在工作中对shared_ptr 的引用存有疑问。这是代码。

for (const auto & aRef : aVec) {
    THROW_RUNTIME_IFNULLPTR(aRef);
    // do sth
}

这是我同事的代码。在我看来,aRef 是一个永远不能为空的引用。虽然有人告诉我(auto &aRef 仍然是一个指针,所以它可能为空。参考只是为了不增加计数器。我对此很困惑。

不过应该​​是这样的

for (const auto & aRef : aVec) {
    // THROW_RUNTIME_IFNULLPTR(aRef);
    if ( aRef ) {
        aRef->getX();
    }
    // do sth
} 

我错了吗?我不认为aRef 是一个指针。

【问题讨论】:

  • 在提供的示例中,aVec 是什么?什么类型?
  • 对不起,是shared_ptr的向量
  • 我想你可以有一个指向空指针的引用。 (编辑:添加了一个逗号:>)
  • aRef 是一个引用,所以它永远不能为空。它可以是一个确实为空的有效指针的别名......如果这就是你的意思。
  • 关于:“参考只是为了不增加计数器。我对此很困惑。” shared_ptr 是一个引用计数指针。每次复制shared_ptr 时,引用计数都会增加。每次销毁副本时,计数都会减少。当引用计数为零时,指针为deleteed。通过使用引用,shared_ptr 不会被复制,从而节省了复制构造和销毁以及引用计数开销。

标签: c++ reference shared-ptr


【解决方案1】:

在我看来,aRef 是一个永远不能为空的引用。

是和不是。引用可以是它所引用的对象可以是任何东西。如果该对象是intstd::stringstd::vector<double>,那么它当然不能为空(或nullptr,准确地说)。

但是,如果该对象是指针,例如 int*void*MyClass*,则它可以是 nullptr,因为指针可以是 nullptr

现在,在您的情况下,被引用的对象是 std::shared_ptr。从技术上讲,它不能是nullptr,但它可以表示 nullptr,因为它处于get() 返回nullptr 的状态。

虽然我被告知(auto &aRef 仍然是一个指针,所以它可能为空。

更准确地说:aRef 仍然是 std::shared_ptr,所以它可能仍然代表 nullptr

【讨论】:

    【解决方案2】:

    std::shared_ptrexplicit operator bool(),所以在这段代码中

    if ( aRef )
    

    将调用该运算符,如果底层指针不为空,则返回true。

    【讨论】:

    【解决方案3】:

    aRef 是一个参考。它是对象的别名。

    指针是一个单独的对象,它可能指向另一个对象。

    在这种情况下,aRef 是对std::shared_ptr<Something> 类型对象的引用。

    代码大致相当于这样:

    auto first = aVec.begin();
    auto last = aVec.end();
    for( ; first != last ; ++first) {
        std::shared_ptr<Something> const& aRef = *first;
        if (aRef.get() != nullptr) {
            aRef->getX();
        }
        else {
            // handle the case where aRef is not pointing at an object
        }
    }
    

    【讨论】:

      猜你喜欢
      • 2020-04-18
      • 2016-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-09-25
      • 1970-01-01
      • 2011-06-19
      相关资源
      最近更新 更多