给定返回unique_ptr的函数,如何使类成为指针的(部分)所有者



这个问题是Why does';t返回std::unique_ptr违反unique_ptr';s已删除的复制构造函数?(此处回答:从函数返回unique_ptr(

这让我回到了我最初面临的问题。

我必须使用一个返回std::unique_ptr的函数(在我的控制之外(。我希望类的实例引用unique_ptr封装的对象,但我不清楚实现这一点所需的语法

我希望这个示例代码能让我的意图变得清晰,因为我找不到正确的模型/语法来编译:我希望class PtrOwner的实例能够";拥有";对由函数getUniquePtr():返回的unique_ptr封装的底层对象的某种形式的引用

// main.cpp
#include <memory>
#include <iostream>
std::unique_ptr<int> getUniquePtr() {
return std::unique_ptr<int>(new int( 42 ));
}
class PtrOwner {
std::unique_ptr<int> p_;
public:
PtrOwner( std::unique_ptr<int> p ) : p_(p) {}
};
int main( int argc, char* argv[] ) {
PtrOwner po( getUniquePtr() );
return 0;
}
$ g++ --version && g++ -g ./main.cpp && ./a.out
g++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
./main.cpp: In constructor ‘PtrOwner::PtrOwner(std::unique_ptr<int>)’:
./main.cpp:13:44: error: use of deleted function ‘std::unique_ptr<_Tp, _Dp>::unique_ptr(const std::unique_ptr<_Tp, _Dp>&) [with _Tp = int; _Dp = std::default_delete<int>]’
PtrOwner( std::unique_ptr<int> p ) : p_(p) {}
^
In file included from /usr/include/c++/6/memory:81:0,
from ./main.cpp:2:
/usr/include/c++/6/bits/unique_ptr.h:359:7: note: declared here
unique_ptr(const unique_ptr&) = delete;
^~~~~~~~~~

实现这一目标的良好做法/公认惯例是什么?我试着摸索PtrOwner拥有shared_ptr的概念,但我也不擅长这个类,也无法实现所需的语法:

// main.cpp
#include <memory>
#include <iostream>
std::unique_ptr<int> getUniquePtr() {
return std::unique_ptr<int>(new int( 42 ));
}
class PtrOwner {
std::shared_ptr<int> p_;
public:
PtrOwner( const std::unique_ptr<int>& p ) : p_(p) {}
};
int main( int argc, char* argv[] ) {
PtrOwner po( getUniquePtr() );
return 0;
}

(我认为第二个代码块的错误太垃圾了,我无法合理地在这里发布(

顶部示例中的构造函数试图复制unique_ptr,但unique_ptr不可复制。

你需要移动它:

#include <utility>
//...
PtrOwner(std::unique_ptr<int>&& p) : p_(std::move(p)) {}

不过,所有权并没有任何部分。PtrOwner现在是所有者。时期

要获得对底层对象的引用,请使用std::unique_ptr::operator*:

int& r = *p_;

r在这里是对底层对象的引用,可用于为对象(例如r = 10;(分配新值,但不拥有该对象。当r超出范围时,该对象将继续存在,当PtrOwner实例超出范围时(或者,如果所有权已转移,当当前拥有的实体超出范围时(,该对象会被销毁。

实现这一目标的良好实践/公认惯例是什么?

接受@TedLingmo的建议。这是很好的做法。我只提供一些额外的一般直觉:

如果你的类持有一个std::unique_ptr而不是一个指针,你基本上可以忘记术语"的使用;指针";在那里。把它想象成一个不透明的、不可复制的对象;您绝对不必担心任何堆存储。它有点像std::vector,但没有复制构造函数。

相关内容

  • 没有找到相关文章

最新更新