简体   繁体   中英

When will the move ctor be invoked?

Given class:

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;
    }
};

and then in main:

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

as you will see from the output the "regular" version of copy ctor and operator= are invoked but not those with rvalue args. So I would like to ask in what circumstances will the move ctor and operator=(C&&) be invoked?

The move constructor will be invoked when the right-hand side is a temporary, or something that has been explicitly cast to C&& either using static_cast<C&&> or 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

IIRC, you have to use C d = std::move(c) to use the move constructor.

An example not tested but that could explain better the use of move constructor :

C&& foo() { C c; return std::move(c); }
std::swap(c,e); // c and e variables declared in your _tmain()

会调用move构造函数。

All of your variables are lvalues and thus cannot be moved implicitly, since you may need to access them later. In addition, copy constructors and assignment operators take const references.

Rvalue references work on, well, rvalues, that is, temporary objects. In order to see the move constructor used, first, you will have to actually create a temporary object. In addition, don't forget that RVO still applies and may well nail any or all of your std::cout calls.

You can create an rvalue from an lvalue using std::move(lvalue).

More realistic example of using move operator would be if you have a static class which returns C&& created on the local stack like this:

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

and then you invoke it like this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM