gpt4 book ai didi

c++ - move 语义如何在这里工作?

转载 作者:行者123 更新时间:2023-12-01 14:40:00 36 4
gpt4 key购买 nike

我有以下示例,但我不确定我是否完全理解 move 语义逻辑:

#include <iostream>
#include <string>
#include <memory>

class Player
{
public:
Player(std::string name)
: m_name(std::move(name)) {}

private:
std::string m_name;
};

int main()
{
std::string s = "Zidane";
std::cout << s << std::endl;

Player player1(s); // not moved
std::cout << s << std::endl; // s = "Zidane"

Player player2(std::move(s)); // moved -> s is empty now
std::cout << s << std::endl;

return 0;
}

我的解释是,在第一种情况下( Player1), name这是 std::string 类型的左值实际上是在 m_name 的 ctor 之前复制的则称为 std::move作用于拷贝,因此最终拷贝为空,其内容已移至 m_name使用 move ctor。这就是为什么原来的论点 s保持不变。这是正确的吗?

第二种情况,不清楚: std::move将左值参数转换为引用右值,然后从那里发生什么?在这种情况下,调用后参数 s 为空。

最佳答案

一个新的std::string总是被创建来“填充”name参数,在 Player(std::string name) 之前叫做。

重载分辨率将决定 std::string 的复制 ctor 或 move ctor将被调用。

案例一:Player player1(s);
新字符串由带有签名 basic_string( const basic_string& other ); 的复制 ctor 创建。 , 因为 's' 是一个左值。

您支付的操作总和是字符串的 1 次 move 和 1 次复制构造:

  • 一份拷贝 ctor,用于 name arg 给 ctor
  • 一个 Action ctor,用于 m_name类员

  • 案例二: Player player2(std::move(s));
    新字符串由 std::string 的 move ctor 创建。 , 签名 basic_string( basic_string&& other ) noexcept;
    在第二种情况下,您调用 std::move , 强制转换 s到一个右值引用。 std::string有 2 个构造函数,一个采用 const std::string& , 另一个取 std::string&& .一个右值引用可以绑定(bind)到一个左值引用和一个右值引用,但是右值引用版本是一个更好的匹配,所以它会被选中。

    您支付的操作总和是字符串的 2 次 move 构造:
  • 一个 Action ctor,用于 name arg 给 ctor
  • 一个 Action ctor,用于 m_name类员

  • 请注意,正如@aschepler 和@underscore_d 所指出的, std::string 的 move ctor不需要清除源字符串。不应依赖于这种行为,因为它不能保证并且取决于字符串的 move ctor 是如何实现的。

    关于c++ - move 语义如何在这里工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59683835/

    36 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com