c++ 移动语义不执行移动
c++ move semantics does not perform move
想法是使用移动语义来避免不必要的复制。
给定以下代码:
#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>)
此外,为什么对主要是代码的 post 有限制?一切都在代码中给出。我对移动语义很感兴趣,所以我创建了 address1 变量来保存一些地址。我使用相同的变量来初始化 Contact 类型的对象(使用移动语义),但是没有执行移动语义并且 address1 变量仍然保持相同的值。
数据成员m_street
和m_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)
顺便说一句:对于像int
这样的内置类型,移动的效果与复制相同。这就是为什么 suite
的值仍然是 123
.
BTW2:对于std::string
、
的移动构造函数
Move constructor. Constructs the string with the contents of other
using move semantics. other
is left in valid, but unspecified state.
移动操作后移动的对象不保证被修改为空。
想法是使用移动语义来避免不必要的复制。 给定以下代码:
#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>)
此外,为什么对主要是代码的 post 有限制?一切都在代码中给出。我对移动语义很感兴趣,所以我创建了 address1 变量来保存一些地址。我使用相同的变量来初始化 Contact 类型的对象(使用移动语义),但是没有执行移动语义并且 address1 变量仍然保持相同的值。
数据成员m_street
和m_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)
顺便说一句:对于像int
这样的内置类型,移动的效果与复制相同。这就是为什么 suite
的值仍然是 123
.
BTW2:对于std::string
、
Move constructor. Constructs the string with the contents of
other
using move semantics.other
is left in valid, but unspecified state.
移动操作后移动的对象不保证被修改为空。