通过rvalue传递不会破坏对象

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了通过rvalue传递不会破坏对象相关的知识,希望对你有一定的参考价值。

我在C ++中移动语义并尝试更好地理解它有点新鲜。我遇到了一些代码,其中函数将rvalue转换为仅移动类型(unique_ptr)。所以我决定为自己做实验。

我定义了一个函数,它将一个rvalue作为参数作为一个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()后,car对象不再有效。 print()的参数是一个合适的接收器参数。

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

我会感激一些更好的解释。

答案

所以要记住的第一件事是std::move被错误命名。它永远不会移动任何东西。它只是通过将它包装在一种特殊的参考中来移动它。

“移动构造函数”是实际移动的东西。例如,std::unique_ptr<T>(std::unique_ptr &&ref)

函数参数是复制或移动构造,具有移动构造的首选项。

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

第二个做了一个正确的举动,并在调用后car将在独特的ptr内部nullptrcar将在print结束时毁灭。

以上是关于通过rvalue传递不会破坏对象的主要内容,如果未能解决你的问题,请参考以下文章

通过导航组件在底部导航片段之间传递数据

将接口从片段传递到kotlin中的活动

在混合 C 和 C++ 代码编程中捕获异常后对象不会被破坏

有没有办法在C ++中通过引用传递rvalue?

当活动被破坏但我必须继续执行片段中的代码时该怎么办?

对左值(lvalue)和右值(rvalue)的两种理解方式