Когда присутствуют оба механизма перемещения и копирования, какой из них будет вызываться?
Ниже представлен класс A, полный конструктора разных типов.
Если я комментирую конструктор перемещения, то конструктор копирования вызывается дважды: один раз для передачи объекта функции fun по значению и другим путем возврата из той же функции.
Фрагмент кода
класс A {
int x;
public :
A() {
cout<<"Default Constructor\n";
}
A(A&& a) : x(a.x){
cout<<"Move Constructor\n";
a.x=0;
}
A(const A& a){
x=a.x;
cout<<"Copy Constructor\n";
}
A fun(A a){
return a;
}
};
int main() {
A a;
A b;
A c;
c=a.fun(b);
}
OUTPUT:
Default Constructor
Default Constructor
Default Constructor
Copy Constructor
Move Constructor
Однако, если присутствует конструктор перемещения, он вызывается вместо конструктора копирования. Может ли кто-нибудь сформулировать это с хорошим примером, так что я буду ясно понимать эту концепцию.
Буду признателен за вашу помощь. Спасибо.
Ответы
Ответ 1
Стандарт допускает специальный случай для случая, когда выражение в выражении return
является автоматической переменной продолжительности. В этом случае перегрузки конструктора выбираются так, как если бы выражение в return
было rvalue
.
Чтобы быть более точным, если выражение в выражении return
было автоматической переменной продолжительности, которая имела право на копирование, или если вы проигнорировали факт, что это аргумент функции, тогда требуется компилятор рассматривать его как rvalue с целью разрешения перегрузки. Обратите внимание, что в С++ 11 выражение оператора return
должно иметь тип cv-unqualified в качестве возвращаемого типа функций. Это немного смягчилось в С++ 14.
Например, в С++ 11 следующий код вызывает конструктор копирования A
вместо конструктора перемещения:
class A
{
};
class B
{
public:
B(A a) : a(std::move(a)){}
A a;
};
B f(A a)
{
return a;///When this is implicitly converted to `B` by calling the constructor `B(a)`, the copy constructor will be invoked in C++11. This behaviour has been fixed in C++14.
}
Ответ 2
в функции A fun (A a) переданная в "копии" A в основном временная переменная. Если конструктор перемещения отсутствует, возвращаемое значение является копией (т.е. Конструктором копирования).
Если есть конструктор перемещения, тогда компилятор может выполнять более эффективную "движущуюся" систематику на временную переменную "A a".