【问题标题】:c++ move semantics does not perform movec ++移动语义不执行移动
【发布时间】:2020-08-29 12:31:20
【问题描述】:

想法是使用移动语义来避免不必要的复制。 给定以下代码:

#include <iostream>
#include <string>
#include <utility>



class Address {
private:
    const std::string m_street;
    const std::string m_city;
    const int m_suite;

public:
    Address(const std::string &street, const std::string &city, int suite) : m_street {std::move(street)},
                                                                            m_city {std::move(city)},
                                                                            m_suite {suite}
    {
    }

    friend std::ostream& operator<<(std::ostream &out, const Address &address)
    {
        out << "Address: (street: " << address.m_street << ", city: " << address.m_city << ", suite: " << address.m_suite << ")\n";

        return out;
    }

    Address(const Address &other) = delete;

    Address& operator=(const Address &other) = delete;

    Address(Address &&other) : m_street {std::move(other.m_street)},
                               m_city {std::move(other.m_city)},
                               m_suite {std::move(other.m_suite)}
    {
    }
};


class Contact {
    const std::string m_name;
    const Address m_address;

public:
    Contact(const std::string &name, Address &address) : m_name {std::move(name)},
                                                        m_address {std::move(address)}
    {
    }

    friend std::ostream& operator<<(std::ostream& out, const Contact &contact)
    {
        out << "Contact: " << contact.m_name << "\n" << contact.m_address << "\n";

        return out;
    }
};


int main()
{
    Address address1 {"123 East Dr", "London", 123};
    Contact john {"John Doe", address1};

    std::cout << john;
    std::cout << address1;

    return 0;
}

我得到以下输出:

Contact: John Doe
Address: (street: 123 East Dr, city: London, suite: 123)

Address: (street: 123 East Dr, city: London, suite: 123)

为什么 address1 变量的内容没有移动?打印输出不应该是

Address: (street: , city: , suite: <whatever>)

另外,为什么对主要是代码的帖子有限制?一切都在代码中给出。我对移动语义很感兴趣,所以我创建了 address1 变量来保存一些地址。我使用相同的变量来初始化 Contact 类型的对象(使用移动语义),但没有执行移动语义,并且 address1 变量仍然保持相同的值。

【问题讨论】:

  • Why isn't the content of the address1 variable moved? 为什么会这样?它不是右值。
  • 但它作为一个引用传递给Contact构造函数,然后执行移动以从中取出一个右值?
  • 最好有Contact(const std::string &amp;name, Address&amp;&amp; address)

标签: c++ c++11 move-semantics


【解决方案1】:

数据成员m_streetm_city被声明为const;然后在Address 的移动构造函数的成员初始化列表中,如m_street {std::move(other.m_street)},使用std::string 的复制构造函数(但不是移动构造函数)。

您可能想要删除 const 限定符,然后您会得到

Contact: John Doe
Address: (street: 123 East Dr, city: London, suite: 123)

Address: (street: , city: , suite: 123)

LIVE

顺便说一句:对于像int 这样的内置类型,移动的效果与复制相同。这就是为什么suite 的值仍然是123

BTW2:对于std::string的移动构造函数,

移动构造函数。使用移动语义构造具有other 内容的字符串。 other 处于有效但未指定的状态。

移动操作后被移动的对象不保证被修改为空。

【讨论】:

  • 也许值得一提的是,一般来说,被移动的对象可以处于任何状态,不被修改是不常见的,但不一定是错误的
  • @idclev463035818 已添加。 std::string 也是如此。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-07-24
  • 2014-08-16
  • 2011-06-11
  • 1970-01-01
  • 2019-01-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多