为什么不调用成员变量的构造函数?

问题描述

请考虑以下课程。如果我自己按照以下方式实现move构造函数,为什么酒吧成员b不移动而是被复制?但是,如果我使用认的move构造函数,那么b会被移动。为什么b(rhs.b)不呼叫bar(bar&&)

我将g ++ 9.2.1与--std = c ++ 11一起使用。

class bar {
public:
    bar() { cout << "bar constructor" << endl; }
    bar(const bar& rhs) { cout << "bar copy constructor" << endl; }
    bar(bar&& rhs) { cout << "bar move constructor" << endl; }
};

class foo {
    bar b;
public:
    foo() { cout << "foo constructor" << endl; }
    foo(const foo& rhs) { cout << "foo copy constructor" << endl; }
    // foo(foo&& rhs) = default;
    foo(foo&& rhs) : b(rhs.b) { cout << "foo move constructor" << endl; } // my version
    //               ^^^^^^^^
};

foo f;
foo g = std::move(f);

解决方法

为什么b(rhs.b)不打bar(bar&&)

因为rhs.b lvalue ,并且 rvalue引用不会绑定到 lvalues 。结果–由于左值引用确实绑定到左值选择了重载bar(const bar&)(即复制构造函数)而不是bar(bar&&)

为了选择move构造函数,您需要在初始化rhs.b的{​​时,以{<utility>std::move()foo标记为“可移动” {1}}成员:

b

这是一种将表达式foo(foo&& rhs): b(std::move(rhs.b)) { /* ... */ } ^^^^^^^^^ 转换为 xvalue (即 rvalue )的表达式,该值绑定到 rvalue引用。因此,这次选择了move构造函数。

但是如果我使用默认的move构造函数,那么rhs.b会被移动。

默认的move构造函数执行成员级移动。