Когда будет запущен ход ctor? - PullRequest
1 голос
/ 05 августа 2010

Данный класс:

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

и затем в основном:

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

как вы увидите из вывода, вызывается «обычная» версия копии ctor и operator=, но не те, которые имеют аргументы rvalue. Поэтому я хотел бы спросить, при каких обстоятельствах будет вызываться перемещение ctor и operator=(C&&)?

Ответы [ 5 ]

7 голосов
/ 05 августа 2010

Конструктор перемещения будет вызываться, когда правая часть является временной, или что-то явно было приведено к 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 голос
/ 05 августа 2010

Все ваши переменные являются lvalues ​​и, следовательно, не могут быть перемещены неявно, так как вам может потребоваться доступ к ним позже. Кроме того, конструкторы копирования и операторы присваивания принимают константные ссылки.

Ссылки на Rvalue работают, ну, на rvalues, то есть на временных объектах. Чтобы увидеть используемый конструктор перемещения, сначала вам нужно будет создать временный объект. Кроме того, не забывайте, что RVO по-прежнему применяется и вполне может использовать любой или все ваши вызовы std :: cout.

Вы можете создать rvalue из lvalue, используя std :: move (lvalue).

1 голос
/ 05 августа 2010
std::swap(c,e); // c and e variables declared in your _tmain()

вызовет конструктор перемещения.

1 голос
/ 05 августа 2010

IIRC, вы должны использовать C d = std::move(c), чтобы использовать конструктор перемещения.

Пример, который не тестировался, но который мог бы лучше объяснить использование конструктора перемещения:

C&& foo() { C c; return std::move(c); }
0 голосов
/ 12 декабря 2012

Более реалистичным примером использования оператора перемещения может быть, если у вас есть статический класс, который возвращает C &&, созданный в локальном стеке, следующим образом:

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

и затем вы вызываете это так:

C x = CreateC(); // move operator is invoked here
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...