【问题标题】:Passing by rvalue does not destroy object通过右值传递不会破坏对象
【发布时间】:2019-04-14 05:24:58
【问题描述】:

我对在 C++ 中移动语义并试图更好地理解它有点陌生。我遇到了一些代码,其中函数将右值转换为仅移动类型(unique_ptr)。所以我决定自己尝试一下。

我定义了一个函数,它将一个右值作为参数传递给一个 unique_ptr,如下所示:

void print(std::unique_ptr<Car>&& car)
{
    std::cout << "Car" << car->Get() << std::endl;
}

Car 类是一个简单的类:

class Car
{
public:
    Car(int i) : N(i) { std::cout << "Car" << N << std::endl; }
    ~Car() { std::cout << "~Car" << N << std::endl; }

    int Get() { return N;  }

private:
    int N;
};

现在如果我这样调用函数:

std::unique_ptr<Car> car = std::make_unique<Car>(99);
print(std::move(car));

我发现调用 print() 函数后 car 对象没有被销毁。在这种情况下,强制转换为右值不会调用移动构造函数。

但是,如果我像这样更改函数定义:

void print(std::unique_ptr<Car> car)
{
    std::cout << "Car" << car->Get() << std::endl;
}

那么调用 print() 后汽车对象不再有效。 print() 的参数是合适的 sink 参数。

这很有趣,因为我读过的所有内容都表明您应该期望一个对象在使用 std::move 后被销毁 - 即它的内部资源不再有效。

如果能得到更好的解释,我将不胜感激。

【问题讨论】:

    标签: c++11 c++14


    【解决方案1】:

    所以首先要记住的是std::move 的名称有误。它永远不会移动任何东西。它只是通过将事物包装在一种特殊的引用中来移动它成为可能。

    “移动构造函数”是执行实际移动的东西。以std::unique_ptr&lt;T&gt;(std::unique_ptr &amp;&amp;ref) 为例。

    函数参数是复制或移动构造,优先考虑移动构造。

    所以,您的第一次尝试只是将其用作参考,从未移动任何东西。您可以使用常规引用(单个 &amp;)获得相同的效果。

    第二个是正确的,在调用car 之后将是唯一ptr 内的nullptr。而car 将在print 结束时销毁。

    【讨论】:

    • 感谢您的解释。我同意在第一种情况下,我不妨使用常规引用 (&)。是否会有通过右值传递的情况?
    猜你喜欢
    • 1970-01-01
    • 2022-01-24
    • 2019-03-01
    • 2018-12-17
    • 1970-01-01
    • 2018-08-29
    • 2011-06-19
    • 2023-03-20
    • 1970-01-01
    相关资源
    最近更新 更多