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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 13:50:04  来源:igfitidea点击:

How can I pass std::unique_ptr into a function

c++c++11unique-ptr

提问by user3690202

How can I pass a std::unique_ptrinto 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_ptrinto 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_ptrinto a function?

为什么我不能将 a 传递unique_ptr给函数?

You cannot do that because unique_ptrhas 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_ptrto 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, ptrdoes 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, ptrstill has ownership of the pointer after the call to MyFunc.

在第一种情况下,ptr在调用 之后仍然拥有指针的所有权MyFunc

回答by Jarod42

As MyFuncdoesn'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_ptrdoesn't have copy on purpose to guaranty to have only one owner.

std::unique_ptr没有故意复制以保证只有一个所有者。

回答by Nielk

Why can I not pass a unique_ptrinto 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_ptris for unique ownership, if you want to pass it as argument try

由于unique_ptr用于唯一所有权,如果您想将其作为参数传递,请尝试

MyFunc(move(ptr));

But after that the state of ptrin mainwill be nullptr.

但在那之后ptrin的状态main将是nullptr