移动ctor什么时候被调用?

时间:2010-08-05 09:18:22

标签: c++ constructor c++11

鉴于课程:

class C
{
public:
    C()
    {
        cout << "Dflt ctor.";
    }
    C(C& obj)
    {
        cout << "Copy ctor.";
    }
    C(C&& obj)
    {
        cout << "Move ctor.";
    }
    C& operator=(C& obj)
    {
        cout << "operator=";
        return obj;
    }
    C& operator=(C&& obj)
    {
        cout << "Move operator=";
        return obj;
    }
};

然后在main:

int main(int argc, char* argv[])
{
    C c;
    C d = c;
    C e;
    e = c;
    return 0;
}

正如您将从输出中看到的那样,复制ctor和operator=的“常规”版本被调用,而不是那些带有rvalue args的版本。所以我想问一下,在什么情况下可以调用ctor和operator=(C&&)

5 个答案:

答案 0 :(得分:7)

当右侧是临时的,或者使用C&&static_cast<C&&>明确转换为std::move的内容时,将调用移动构造函数。

C c;
C d(std::move(c)); // move constructor
C e(static_cast<C&&>(c)); // move constructor
C f;
f=std::move(c); // move assignment
f=static_cast<C&&>(c); // move assignment
C g((C())); // move construct from temporary (extra parens needed for parsing)
f=C(); // move assign from temporary

答案 1 :(得分:1)

IIRC,您必须使用C d = std::move(c)来使用移动构造函数。

未经测试的示例,但可以更好地解释移动构造函数的使用:

C&& foo() { C c; return std::move(c); }

答案 2 :(得分:1)

std::swap(c,e); // c and e variables declared in your _tmain()

会调用move构造函数。

答案 3 :(得分:1)

所有变量都是左值,因此无法隐式移动,因为您可能需要稍后访问它们。另外,复制构造函数和赋值运算符采用const引用。

Rvalue引用可以处理rvalues,即临时对象。为了查看使用的移动构造函数,首先,您必须实际创建一个临时对象。此外,不要忘记RVO仍然适用,并且可能会修复任何或所有std :: cout呼叫。

您可以使用std :: move(左值)从左值创建右值。

答案 4 :(得分:-1)

使用移动运算符的更现实的例子是,如果你有一个静态类,它返回C&amp;&amp;在本地堆栈上创建如下:

static C&& CreateC()
{
   C c();
   //do something with your object
   return c;
}

然后你这样调用它:

C x = CreateC(); // move operator is invoked here