我很惊讶这没有显示在我的搜索结果中,我认为有人会在之前问过这个,考虑到C++ 11中移动语义的用处:
(原因等比与现有代码的兼容性问题,那是.)
考虑一个X具有N成员变量的类,每个类都有一些可复制和可移动的类型,以及N相应的setter函数.在C++ 98中,定义X可能如下所示:
class X
{
public:
void set_a(A const& a) { _a = a; }
void set_b(B const& b) { _b = b; }
...
private:
A _a;
B _b;
...
};
Run Code Online (Sandbox Code Playgroud)
X上面类的setter函数可以绑定到左值和右值参数.根据实际的说法,这可能导致创建临时的,并会最终导致的分配副本; 因此,此设计不支持不可复制的类型.
使用C++ 11,我们可以移动语义,完美转发和通用引用(Scott Meyers的术语),通过以下方式重写它们,可以更有效和广泛地使用setter函数:
class X
{
public:
template<typename T>
void set_a(T&& a) { _a = std::forward<T>(a); }
template<typename T>
void set_b(T&& b) { _b = std::forward<T>(b); } …Run Code Online (Sandbox Code Playgroud) c++ move-semantics perfect-forwarding c++11 universal-reference
当类中有一个未定义移动操作的成员时,我很难理解隐式移动操作:
int main() {
struct A // no move: move = copy
{
A() = default;
A(const A&) {
cout << "A'copy-ctor\n";
};
A& operator=(const A&) {
cout << "A'copy-assign\n";
return *this;
}
};
struct B
{
B() = default;
A a; // does this make B non-moveable?
unique_ptr<int> upi;
// B(B&&) noexcept = default;
// B& operator=(B&&)noexcept = default;
};
A a;
A a2 = std::move(a); // ok use copy ctor instead of move one
a2 = std::move(a); // …Run Code Online (Sandbox Code Playgroud) c++ copy-constructor move-constructor implicit-methods c++11
Nicolai M. Josuttis 在他的《C++ Move Semantics》一书中指出,使用生成的移动构造函数在可移动成员中移动包含不可移动成员的对象会移动除不可移动成员(被复制)之外的所有成员。下面的代码片段是书中示例的变体。
#include <iostream>
class Copyable {
std::string name;
public:
explicit Copyable(std::string name): name(std::move(name)) {}
// Copying enabled
Copyable(const Copyable& other): name(other.name) {
std::cout << "Copyable copy ctor" << std::endl;
}
Copyable& operator=(const Copyable& other) {
name=other.name;
std::cout << "Copyable op=" << std::endl;
return *this;
}
// Moving disabled with no copy fallback
Copyable(Copyable&&) = delete;
Copyable& operator=(Copyable&&) = delete;
};
class Movable {
std::string name;
public:
explicit Movable(std::string name): name(std::move(name)) {}
// Copying enabled
Movable(const …Run Code Online (Sandbox Code Playgroud)