提问人:Sami 提问时间:6/26/2023 最后编辑:ProgmanSami 更新时间:6/26/2023 访问量:106
了解 std::move 和 std::unique_ptr 中的所有权转让 C++
Understanding std::move and Ownership Transfer with std::unique_ptr in C++
问:
我已经编写了两组函数,F1/test1 和 F2/test2,我正在尝试了解这些函数中 std::move 的行为和 std::unique_ptr 所有权转移的差异。代码如下:
void F1(std::unique_ptr<Dog>&& uPtr)
{
std::cout << "F1 \n";
}
void test1()
{
std::unique_ptr<Dog> pD(new Dog("Gunner"));
F1(std::move(pD));
if (pD == nullptr)
{
std::cout << "Null\n";
}
std::cout << "Test \n";
}
void F2(std::unique_ptr<Dog> uPtr)
{
std::cout << "F2 \n";
}
void test2()
{
std::unique_ptr<Dog> pD(new Dog("Smokey"));
F2(std::move(pD));
if (pD == nullptr)
{
std::cout << "Null\n";
}
std::cout << "Test \n";
}
在 test1 中,使用 std::move(pD) 作为参数调用 F1,其中 uPtr 是对 std::unique_ptr 的右值引用。调用 F1 后,我检查了 pD 是否为 null。我期望 pD 为 null,因为 std::move(pD) 用于将其传递给 F1,但它不是 null。为什么会这样?
在 test2 中,使用 std::move(pD) 作为参数调用 F2,其中 uPtr 是 std::unique_ptr 类型的按值参数。调用 F2 后,我检查了 pD 是否为 null。在本例中,pD 为 null。正如我所料,因为 std::move(pD) 用于将其传递给 F2,但为什么此行为与 test1 不同?
任何帮助将不胜感激!
答:
这只是对 r 值参考的转换
F1(std::move(pD));
这
void F1(std::unique_ptr<Dog>&& uPtr)
{
std::cout << "F1 \n";
}
实际上对 uPTR 没有任何作用。它可以假设std_ptr即将被销毁,并将其保持在不确定但有效的状态。你的不这样做。
F2
正在使用 Move 构造函数,https://en.cppreference.com/w/cpp/memory/unique_ptr/unique_ptr 查看构造函数 5。
在完成对移动构造函数或移动赋值运算符的调用之前,不会移动对象。 只是从左值到右值的强制转换运算符,此时实际上不会移动任何数据。一个更好的名字是,但这会有点冗长。std::move
std::move
std::cast_to_rvalue
对于 ,指针由右值引用传递,因此函数仍使用来自调用方的实例。由于在函数中未触及,因此原始指针仍将有效。F1
uPtr
对于 ,指针是按值传递的,因此在进入函数以创建新对象之前必须调用移动构造函数。即使指针在函数中未触及,移动操作也已发生,因此调用方的实例会受到影响。F2
评论
std::move(x)
std::move
T &&
T
std::move
只是一个强制转换为右值的引用。有关详细信息,请参阅 en.cppreference.com/w/cpp/utility/move。