C++ 如何将 std::unique_ptr 传递给函数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/30905487/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I pass std::unique_ptr into a function
提问by user3690202
How can I pass a std::unique_ptr
into a function? Lets say I have the following class:
如何将 a 传递std::unique_ptr
给函数?假设我有以下课程:
class A
{
public:
A(int val)
{
_val = val;
}
int GetVal() { return _val; }
private:
int _val;
};
The following does not compile:
以下不编译:
void MyFunc(unique_ptr<A> arg)
{
cout << arg->GetVal() << endl;
}
int main(int argc, char* argv[])
{
unique_ptr<A> ptr = unique_ptr<A>(new A(1234));
MyFunc(ptr);
return 0;
}
Why can I not pass a std::unique_ptr
into a function? Surely this is the primary purpose of the construct? Or did the C++ committee intend for me to fall back to raw C-style pointers and pass it like this:
为什么我不能将 a 传递std::unique_ptr
给函数?这肯定是构造的主要目的吗?或者 C++ 委员会是否打算让我回到原始 C 风格的指针并像这样传递它:
MyFunc(&(*ptr));
And most strangely of all, why is this an OK way of passing it? It seems horribly inconsistent:
最奇怪的是,为什么这是通过它的好方法?这似乎非常不一致:
MyFunc(unique_ptr<A>(new A(1234)));
回答by Bill Lynch
There's basically two options here:
这里基本上有两种选择:
Pass the smart pointer by reference
通过引用传递智能指针
void MyFunc(unique_ptr<A> & arg)
{
cout << arg->GetVal() << endl;
}
int main(int argc, char* argv[])
{
unique_ptr<A> ptr = unique_ptr<A>(new A(1234));
MyFunc(ptr);
}
Move the smart pointer into the function argument
将智能指针移动到函数参数中
Note that in this case, the assertion will hold!
请注意,在这种情况下,断言将成立!
void MyFunc(unique_ptr<A> arg)
{
cout << arg->GetVal() << endl;
}
int main(int argc, char* argv[])
{
unique_ptr<A> ptr = unique_ptr<A>(new A(1234));
MyFunc(move(ptr));
assert(ptr == nullptr)
}
回答by Mark Tolonen
You're passing it by value, which implies making a copy. That wouldn't be very unique, would it?
您通过值传递它,这意味着制作副本。那不会很独特吧?
You could move the value, but that implies passing ownership of the object and control of its lifetime to the function.
您可以移动该值,但这意味着将对象的所有权及其生命周期的控制权传递给函数。
If the lifetime of the object is guaranteed to exist over the lifetime of the call to MyFunc, just pass a raw pointer via ptr.get()
.
如果对象的生命周期保证在调用 MyFunc 的生命周期内存在,只需通过ptr.get()
.
回答by R Sahu
Why can I not pass a
unique_ptr
into a function?
为什么我不能将 a 传递
unique_ptr
给函数?
You cannot do that because unique_ptr
has a move constructor but not a copy constructor. According to the standard, when a move constructor is defined but a copy constructor is not defined, the copy constructor is deleted.
你不能这样做,因为unique_ptr
有一个移动构造函数但没有一个复制构造函数。根据标准,当定义了移动构造函数但未定义复制构造函数时,将删除复制构造函数。
12.8 Copying and moving class objects
...
7 If the class definition does not explicitly declare a copy constructor, one is declared implicitly. If the class definition declares a move constructor or move assignment operator, the implicitly declared copy constructor is defined as deleted;
12.8 复制和移动类对象
...
7 如果类定义未显式声明复制构造函数,则隐式声明一个。如果类定义声明了移动构造函数或移动赋值运算符,则隐式声明的复制构造函数被定义为已删除;
You can pass the unique_ptr
to the function by using:
您可以unique_ptr
使用以下方法将 传递给函数:
void MyFunc(std::unique_ptr<A>& arg)
{
cout << arg->GetVal() << endl;
}
and use it like you have:
并像您一样使用它:
or
或者
void MyFunc(std::unique_ptr<A> arg)
{
cout << arg->GetVal() << endl;
}
and use it like:
并使用它:
std::unique_ptr<A> ptr = std::unique_ptr<A>(new A(1234));
MyFunc(std::move(ptr));
Important Note
重要的提示
Please note that if you use the second method, ptr
does not have ownership of the pointer after the call to std::move(ptr)
returns.
请注意,如果您使用第二种方法,ptr
则在调用std::move(ptr)
返回后不拥有指针的所有权。
void MyFunc(std::unique_ptr<A>&& arg)
would have the same effect as void MyFunc(std::unique_ptr<A>& arg)
since both are references.
void MyFunc(std::unique_ptr<A>&& arg)
将具有相同的效果,void MyFunc(std::unique_ptr<A>& arg)
因为两者都是引用。
In the first case, ptr
still has ownership of the pointer after the call to MyFunc
.
在第一种情况下,ptr
在调用 之后仍然拥有指针的所有权MyFunc
。
回答by Jarod42
As MyFunc
doesn't take ownership, it would be better to have:
由于MyFunc
不拥有所有权,最好拥有:
void MyFunc(const A* arg)
{
assert(arg != nullptr); // or throw ?
cout << arg->GetVal() << endl;
}
or better
或更好
void MyFunc(const A& arg)
{
cout << arg.GetVal() << endl;
}
If you really want to take ownership, you have to move your resource:
如果你真的想拥有所有权,你必须移动你的资源:
std::unique_ptr<A> ptr = std::make_unique<A>(1234);
MyFunc(std::move(ptr));
or pass directly a r-value reference:
或直接传递 r 值引用:
MyFunc(std::make_unique<A>(1234));
std::unique_ptr
doesn't have copy on purpose to guaranty to have only one owner.
std::unique_ptr
没有故意复制以保证只有一个所有者。
回答by Nielk
Why can I not pass a
unique_ptr
into a function?
为什么我不能将 a 传递
unique_ptr
给函数?
You can, but not by copy - because std::unique_ptr<>
is not copy-constructible.
您可以,但不能通过复制 - 因为std::unique_ptr<>
不可复制构造。
Surely this is the primary purpose of the construct?
这肯定是构造的主要目的吗?
Among other things, std::unique_ptr<>
is designed to unequivocally mark uniqueownership (as opposed to std::shared_ptr<>
).
除其他外,std::unique_ptr<>
旨在明确标记 唯一所有权(与 相对std::shared_ptr<>
)。
And most strangely of all, why is this an OK way of passing it?
最奇怪的是,为什么这是通过它的好方法?
Because in that case, there is no copy-construction.
因为在那种情况下,没有复制构造。
回答by 0x6773
Since unique_ptr
is for unique ownership, if you want to pass it as argument try
由于unique_ptr
用于唯一所有权,如果您想将其作为参数传递,请尝试
MyFunc(move(ptr));
But after that the state of ptr
in main
will be nullptr
.
但在那之后ptr
in的状态main
将是nullptr
。