【问题标题】:How to return a smart pointer to a member variable?如何将智能指针返回到成员变量?
【发布时间】:2015-06-12 11:39:45
【问题描述】:

我正在尝试使用智能指针为类成员变量创建访问器。代码如下:

class MyResource
{
};

class MyClass
{
public:
    std::unique_ptr<MyResource> getResource();
private:
    std::unique_ptr<MyResource> resource;
};

std::unique_ptr<MyResource> MyClass::getResource()
{
    return this->resource;
}

我在编译时遇到的错误:

无法访问在类 'std::unique_ptr<_ty>' 中声明的私有成员

将.get 添加到this-&gt;resource 当然是行不通的,因为返回类型发生了变化。

我不应该在这里使用 unique_ptr 吗?这只是语法问题吗?我完全走错了吗?

我的智能指针背景: 几年来我一直在使用普通的旧指针,部分原因是我找不到关于何时使用哪种类型的智能指针以及如何使用它们的可靠解释。我厌倦了找借口,所以我只是潜入。我想我了解什么是智能指针以及为什么要使用它们,但我对细节了解甚少。目前我完全迷失在theendlessQ&Aaboutsmartpointers。

【问题讨论】:

  • 您不应该在这里使用唯一指针。按值返回或使其成为共享指针。
  • @dwcanillas 或者通过引用或原始指针返回。
  • @Angew 是的,没错。唯一指针的全部意义在于它们是唯一的,有一个指针指向一个对象。
  • @OP 您知道std::unique_ptr&lt;MyResource&gt; MyClass::getResource() 会将所有权转移给调用者吗?这很可能不是你想要的,除非设计一个工厂。
  • 注意:没有 std::move (std::forward) 就不能转让所有权,请参阅 Barry 的回答

标签: c++ c++11 smart-pointers


【解决方案1】:

了解智能指针最重要的一点是,“指针”方面不是它们语义的基本部分。存在智能指针以表示所有权。所有权被定义为清理的责任。

一个唯一的指针说:“我是指针的唯一所有者。当我超出范围时,我会销毁它。”

共享指针说:“我是一群朋友中的一员,他们对指针负责。我们中最后一个超出范围的人会破坏它。”

(在现代 C++ 程序中,)原始指针或引用说:“我不拥有指针,我只是观察它。其他人负责销毁它。”

在您的情况下,使用unique_ptr 作为成员类型意味着MyClass 拥有MyResource 对象。如果 getter 应该转移所有权(也就是说,如果 MyClass 将资源放弃给调用 getter 的人),则返回 unique_ptr 是合适的(并且您必须 return std::move(resource); 来获得所有权显式转移)。

如果 getter 不 应该放弃所有权(我认为这是可能的情况),只需返回一个普通的旧指针(如果返回空指针是一个选项)或一个普通的旧指针参考(如果返回 null 不是一个选项)。

【讨论】:

  • 虽然另一个答案获得了更多的选票,但由于解释,这个答案对我个人最有帮助。现在我想(我希望)我终于明白了这一点。
  • @David 这正是 SO 有投票和接受概念的原因 :-) 很高兴能提供帮助。
  • 对于第三种情况,我们很快也会有std::experimental::observer_ptr。
【解决方案2】:

这里有几个选项,具体取决于您希望班级遵守的语义。

  1. 您想放弃资源的所有权:

    std::unique_ptr<MyResource> MyClass::releaseResource() {
        return std::move(this->resource);
    }
    
  2. 您想保持唯一的所有权,但让其他人使用它:

    MyResource& MyClass::getResource() {
        assert(this->resource);
        return *(this->resource);
    }
    
  3. 您希望共享所有权,因此如果 MyClass 超出范围,资源不会被破坏:将所有内容切换到 std::shared_ptr&lt;MyResource&gt; 并仍按值返回。

【讨论】:

  • 你速度更快,有一个 +1 :-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-20
相关资源
最近更新 更多