这个问题是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
,但没有复制构造函数。