如何将 std::unique_ptr 传递给函数
How can I pass std::unique_ptr into a function
如何将 std::unique_ptr
传递给函数?假设我有以下 class:
class A
{
public:
A(int val)
{
_val = val;
}
int GetVal() { return _val; }
private:
int _val;
};
以下不编译:
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;
}
为什么我不能将 std::unique_ptr
传递给函数?这肯定是构造的主要目的吗?或者 C++ 委员会是否打算让我退回到原始 C 风格的指针并像这样传递它:
MyFunc(&(*ptr));
最奇怪的是,为什么这是一种正确的传递方式?这似乎非常不一致:
MyFunc(unique_ptr<A>(new A(1234)));
这里基本上有两个选项:
通过引用传递智能指针
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);
}
将智能指针移动到函数参数中
请注意,在这种情况下,断言将成立!
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)
}
因为 unique_ptr
是唯一所有权,如果你想把它作为参数传递,试试
MyFunc(move(ptr));
但之后 ptr
在 main
中的状态将是 nullptr
.
您正在按值传递它,这意味着制作副本。那不会很独特吧?
您可以移动该值,但这意味着将对象的所有权和其生命周期的控制权传递给函数。
如果保证对象的生命周期存在于调用 MyFunc 的生命周期内,只需通过 ptr.get()
传递一个原始指针。
Why can I not pass a unique_ptr
into a function?
你可以,但不能复制 - 因为 std::unique_ptr<>
不可复制构造。
Surely this is the primary purpose of the construct?
除其他外,std::unique_ptr<>
旨在明确标记 唯一 所有权(与 std::shared_ptr<>
相对)。
And most strangely of all, why is this an OK way of passing it?
因为在那种情况下,没有复制构造。
Why can I not pass a unique_ptr
into a function?
你不能那样做,因为 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;
您可以使用以下方法将 unique_ptr
传递给函数:
void MyFunc(std::unique_ptr<A>& arg)
{
cout << arg->GetVal() << endl;
}
并像您一样使用它:
或
void MyFunc(std::unique_ptr<A> arg)
{
cout << arg->GetVal() << endl;
}
并像这样使用它:
std::unique_ptr<A> ptr = std::unique_ptr<A>(new A(1234));
MyFunc(std::move(ptr));
重要提示
请注意,如果您使用第二种方法,ptr
在调用std::move(ptr)
后没有指针的所有权returns。
void MyFunc(std::unique_ptr<A>&& arg)
与 void MyFunc(std::unique_ptr<A>& arg)
具有相同的效果,因为两者都是引用。
在第一种情况下,ptr
在调用MyFunc
后仍然拥有指针的所有权。
由于MyFunc
没有所有权,最好有:
void MyFunc(const A* arg)
{
assert(arg != nullptr); // or throw ?
cout << arg->GetVal() << endl;
}
或更好
void MyFunc(const A& arg)
{
cout << arg.GetVal() << endl;
}
如果你真的想获得所有权,你必须移动你的资源:
std::unique_ptr<A> ptr = std::make_unique<A>(1234);
MyFunc(std::move(ptr));
或者直接传递一个右值引用:
MyFunc(std::make_unique<A>(1234));
std::unique_ptr
故意没有副本以保证只有一个所有者。
将 std::unique_ptr<T>
作为值传递给函数是行不通的,因为正如你们所说,unique_ptr
不可复制。
这个呢?
std::unique_ptr<T> getSomething()
{
auto ptr = std::make_unique<T>();
return ptr;
}
此代码有效
如何将 std::unique_ptr
传递给函数?假设我有以下 class:
class A
{
public:
A(int val)
{
_val = val;
}
int GetVal() { return _val; }
private:
int _val;
};
以下不编译:
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;
}
为什么我不能将 std::unique_ptr
传递给函数?这肯定是构造的主要目的吗?或者 C++ 委员会是否打算让我退回到原始 C 风格的指针并像这样传递它:
MyFunc(&(*ptr));
最奇怪的是,为什么这是一种正确的传递方式?这似乎非常不一致:
MyFunc(unique_ptr<A>(new A(1234)));
这里基本上有两个选项:
通过引用传递智能指针
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);
}
将智能指针移动到函数参数中
请注意,在这种情况下,断言将成立!
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)
}
因为 unique_ptr
是唯一所有权,如果你想把它作为参数传递,试试
MyFunc(move(ptr));
但之后 ptr
在 main
中的状态将是 nullptr
.
您正在按值传递它,这意味着制作副本。那不会很独特吧?
您可以移动该值,但这意味着将对象的所有权和其生命周期的控制权传递给函数。
如果保证对象的生命周期存在于调用 MyFunc 的生命周期内,只需通过 ptr.get()
传递一个原始指针。
Why can I not pass a
unique_ptr
into a function?
你可以,但不能复制 - 因为 std::unique_ptr<>
不可复制构造。
Surely this is the primary purpose of the construct?
除其他外,std::unique_ptr<>
旨在明确标记 唯一 所有权(与 std::shared_ptr<>
相对)。
And most strangely of all, why is this an OK way of passing it?
因为在那种情况下,没有复制构造。
Why can I not pass a
unique_ptr
into a function?
你不能那样做,因为 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;
您可以使用以下方法将 unique_ptr
传递给函数:
void MyFunc(std::unique_ptr<A>& arg)
{
cout << arg->GetVal() << endl;
}
并像您一样使用它:
或
void MyFunc(std::unique_ptr<A> arg)
{
cout << arg->GetVal() << endl;
}
并像这样使用它:
std::unique_ptr<A> ptr = std::unique_ptr<A>(new A(1234));
MyFunc(std::move(ptr));
重要提示
请注意,如果您使用第二种方法,ptr
在调用std::move(ptr)
后没有指针的所有权returns。
void MyFunc(std::unique_ptr<A>&& arg)
与 void MyFunc(std::unique_ptr<A>& arg)
具有相同的效果,因为两者都是引用。
在第一种情况下,ptr
在调用MyFunc
后仍然拥有指针的所有权。
由于MyFunc
没有所有权,最好有:
void MyFunc(const A* arg)
{
assert(arg != nullptr); // or throw ?
cout << arg->GetVal() << endl;
}
或更好
void MyFunc(const A& arg)
{
cout << arg.GetVal() << endl;
}
如果你真的想获得所有权,你必须移动你的资源:
std::unique_ptr<A> ptr = std::make_unique<A>(1234);
MyFunc(std::move(ptr));
或者直接传递一个右值引用:
MyFunc(std::make_unique<A>(1234));
std::unique_ptr
故意没有副本以保证只有一个所有者。
将 std::unique_ptr<T>
作为值传递给函数是行不通的,因为正如你们所说,unique_ptr
不可复制。
这个呢?
std::unique_ptr<T> getSomething()
{
auto ptr = std::make_unique<T>();
return ptr;
}
此代码有效