【问题标题】:How to change ownership of pointer in C++'11?如何更改 C++'11 中指针的所有权?
【发布时间】:2013-07-09 16:42:09
【问题描述】:

我想使用unique_ptr<NativeWindow> 存储一个指向我的本机窗口实例的指针,以便在Window 对象超出范围时保证它被释放。

// This would be maintained by a window manager
unique_ptr<Window> window;

void Foo() {
    NativeWindow *pNativeWindow = createNativeWindow();
    window = new Window(pNativeWindow);
}

// ...

class Window {
private:
    unique_ptr<NativeWindow> _nativeWindow;
public:
    inline NativeWindow& GetNativeWindow() {
        return *_nativeWindow;
    }

// ...

Window::Window(NativeWindow&& nativeWindow)
    : _nativeWindow(std::move(nativeWindow))
{
}

我很难理解移动语义,并且会发现从这个示例中学习起来更容易。如果这是香草指针,我会很好,但我正在尝试理解新方法!

【问题讨论】:

  • unique_ptr&lt;T&gt; second = first;
  • 这里没有问题。
  • 对不起,我应该更具体,我收到以下错误消息,上面的代码:Error 1 error C2664: 'std::unique_ptr&lt;_Ty&gt;::unique_ptr(std::nullptr_t) throw()' : cannot convert parameter 1 from 'NativeWindow' to 'std::nullptr_t'
  • @H2CO3 不是unique_ptr&lt;T&gt; second = std::move(first);?
  • @H2CO3 不,它仍然无法正常工作。 unique_ptr 不会转移所有权,除非您明确地 std::move.release() 托管指针。如果它符合您的要求,我们就不需要它,auto_ptr 就足够了。

标签: c++ std move-semantics unique-ptr


【解决方案1】:

Window 构造函数应该采用NativeWindow *,而不是NativeWindow&amp;&amp;

Window::Window(NativeWindow* nativeWindow)
    : _nativeWindow(nativeWindow)
{
}

应该可以,但我建议您将参数更改为unique_ptr&lt;NativeWindow&gt;。这清楚地表明Window 对象正在假定NativeWindow 参数的所有权。

Window::Window(std::unique_ptr<NativeWindow> nativeWindow)
    : _nativeWindow(std::move(nativeWindow))
{
}

【讨论】:

  • 理想情况下,CreateNativeWindow 也应该返回 unique_ptr&lt;NativeWindow&gt;
  • 好的,我已将代码更改为此,现在从我的工厂函数返回unique_ptr&lt;NativeWindow&gt;,但我仍然收到编译错误。我有window.reset(new Window(nativeWindow));,上面写着error C2248: 'std::unique_ptr&lt;_Ty&gt;::unique_ptr' : cannot access private member declared in class 'std::unique_ptr&lt;_Ty&gt;'。如上所述,我已将构造函数更改为Window::Window(std::unique_ptr&lt;NativeWindow&gt; nativeWindow)
  • @LeaHayes 听起来您正试图在某处复制unique_ptr。如果您的createNativeWindow 函数现在返回unique_ptr,则在调用构造函数时需要movewindow.reset(new Window(std::move(nativeWindow)));
  • 是的,做到了,现在可以正常编译了 :) 所以在 C++'11 中似乎非常需要 std::move
  • @LeaHayes 当您想指示可以移动某些对象时需要它。在这种情况下,您可以通过使用 window.reset(new Window(createNativeWindow())); 避免调用它(针对您的上述评论)auto_ptr 已弃用。
猜你喜欢
  • 2016-12-30
  • 1970-01-01
  • 2020-03-28
  • 1970-01-01
  • 2019-12-23
  • 2012-07-07
  • 1970-01-01
  • 1970-01-01
  • 2013-03-21
相关资源
最近更新 更多