通过rvalue传递不会破坏对象

问题描述 投票:0回答:1

我在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之后销毁一个对象 - 即它的内部资源不再有效。

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

c++11 c++14
1个回答
0
投票

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

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

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.